1893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
2893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   rpng - simple PNG display program                               rpng-x.c
4893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
5893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   This program decodes and displays PNG images, with gamma correction and
6893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   optionally with a user-specified background color (in case the image has
7893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   transparency).  It is very nearly the most basic PNG viewer possible.
8893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   This version is for the X Window System (tested by author under Unix and
9893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   by Martin Zinser under OpenVMS; may work under OS/2 with some tweaking).
10893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
11893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   to do:
12893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 8-bit (colormapped) X support
13893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - use %.1023s to simplify truncation of title-bar string?
14893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
15893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------
16893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
17893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   Changelog:
18893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.01:  initial public release
19893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.02:  modified to allow abbreviated options; fixed long/ulong mis-
20893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              match; switched to png_jmpbuf() macro
21893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.10:  added support for non-default visuals; fixed X pixel-conversion
22893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.11:  added extra set of parentheses to png_jmpbuf() macro; fixed
23893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              command-line parsing bug
24893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.12:  fixed some small X memory leaks (thanks to Fran�ois Petitjean)
25893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.13:  fixed XFreeGC() crash bug (thanks to Patrick Welche)
26893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.14:  added support for X resources (thanks to Gerhard Niklasch)
27893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 2.00:  dual-licensed (added GNU GPL)
28893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 2.01:  fixed improper display of usage screen on PNG error(s)
29893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
30893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------
31893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
32893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      Copyright (c) 1998-2008 Greg Roelofs.  All rights reserved.
33893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
34893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      This software is provided "as is," without warranty of any kind,
35893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      express or implied.  In no event shall the author or contributors
36893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      be held liable for any damages arising in any way from the use of
37893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      this software.
38893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
39893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      The contents of this file are DUAL-LICENSED.  You may modify and/or
40893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      redistribute this software according to the terms of one of the
41893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      following two licenses (at your option):
42893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
43893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
44893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      LICENSE 1 ("BSD-like with advertising clause"):
45893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
46893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      Permission is granted to anyone to use this software for any purpose,
47893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      including commercial applications, and to alter it and redistribute
48893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      it freely, subject to the following restrictions:
49893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
50893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      1. Redistributions of source code must retain the above copyright
51893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         notice, disclaimer, and this list of conditions.
52893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      2. Redistributions in binary form must reproduce the above copyright
53893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         notice, disclaimer, and this list of conditions in the documenta-
54893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         tion and/or other materials provided with the distribution.
55893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      3. All advertising materials mentioning features or use of this
56893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         software must display the following acknowledgment:
57893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
58893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            This product includes software developed by Greg Roelofs
59893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            and contributors for the book, "PNG: The Definitive Guide,"
60893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            published by O'Reilly and Associates.
61893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
62893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
63893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      LICENSE 2 (GNU GPL v2 or later):
64893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
65893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      This program is free software; you can redistribute it and/or modify
66893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      it under the terms of the GNU General Public License as published by
67893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      the Free Software Foundation; either version 2 of the License, or
68893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      (at your option) any later version.
69893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
70893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      This program is distributed in the hope that it will be useful,
71893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      but WITHOUT ANY WARRANTY; without even the implied warranty of
72893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
73893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      GNU General Public License for more details.
74893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
75893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      You should have received a copy of the GNU General Public License
76893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      along with this program; if not, write to the Free Software Foundation,
77893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
78893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
79893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
80893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
81893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define PROGNAME  "rpng-x"
82893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define LONGNAME  "Simple PNG Viewer for X"
83893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define VERSION   "2.01 of 16 March 2008"
84893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define RESNAME   "rpng"	/* our X resource application name */
85893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define RESCLASS  "Rpng"	/* our X resource class name */
86893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
87893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <stdio.h>
88893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <stdlib.h>
89893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <string.h>
90893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <time.h>
91893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <X11/Xlib.h>
92893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <X11/Xutil.h>
93893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <X11/Xos.h>
94893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <X11/keysym.h>
95893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
96893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* #define DEBUG  :  this enables the Trace() macros */
97893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
98893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include "readpng.h"   /* typedefs, common macros, readpng prototypes */
99893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* could just include png.h, but this macro is the only thing we need
102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * (name and typedefs changed to local versions); note that side effects
103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * only happen with alpha (which could easily be avoided with
104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * "ush acopy = (alpha);") */
105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define alpha_composite(composite, fg, alpha, bg) {               \
107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ush temp = ((ush)(fg)*(ush)(alpha) +                          \
108893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128);  \
109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    (composite) = (uch)((temp + (temp >> 8)) >> 8);               \
110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
113893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* local prototypes */
114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int  rpng_x_create_window(void);
115893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int  rpng_x_display_image(void);
116893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void rpng_x_cleanup(void);
117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int  rpng_x_msb(ulg u32val);
118893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
119893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
120893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic char titlebar[1024], *window_name = titlebar;
121893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic char *appname = LONGNAME;
122893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic char *icon_name = PROGNAME;
123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic char *res_name = RESNAME;
124893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic char *res_class = RESCLASS;
125893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic char *filename;
126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic FILE *infile;
127893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic char *bgstr;
129893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic uch bg_red=0, bg_green=0, bg_blue=0;
130893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic double display_exponent;
132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic ulg image_width, image_height, image_rowbytes;
134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int image_channels;
135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic uch *image_data;
136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* X-specific variables */
138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic char *displayname;
139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic XImage *ximage;
140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic Display *display;
141893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int depth;
142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic Visual *visual;
143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic XVisualInfo *visual_list;
144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int RShift, GShift, BShift;
145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic ulg RMask, GMask, BMask;
146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic Window window;
147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic GC gc;
148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic Colormap colormap;
149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int have_nondefault_visual = FALSE;
151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int have_colormap = FALSE;
152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int have_window = FALSE;
153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int have_gc = FALSE;
154893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*
155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectulg numcolors=0, pixels[256];
156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectush reds[256], greens[256], blues[256];
157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
160893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectint main(int argc, char **argv)
163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
164893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef sgi
165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    char tmpline[80];
166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    char *p;
168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int rc, alen, flen;
169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int error = 0;
170893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int have_bg = FALSE;
171893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    double LUT_exponent;               /* just the lookup table */
172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    double CRT_exponent = 2.2;         /* just the monitor */
173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    double default_display_exponent;   /* whole display system */
174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XEvent e;
175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    KeySym k;
176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    displayname = (char *)NULL;
179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    filename = (char *)NULL;
180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* First set the default value for our display-system exponent, i.e.,
183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * the product of the CRT exponent and the exponent corresponding to
184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * the frame-buffer's lookup table (LUT), if any.  This is not an
185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * exhaustive list of LUT values (e.g., OpenStep has a lot of weird
186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * ones), but it should cover 99% of the current possibilities. */
187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(NeXT)
189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    LUT_exponent = 1.0 / 2.2;
190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /*
191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (some_next_function_that_returns_gamma(&next_gamma))
192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        LUT_exponent = 1.0 / next_gamma;
193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     */
194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#elif defined(sgi)
195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    LUT_exponent = 1.0 / 1.7;
196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* there doesn't seem to be any documented function to get the
197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * "gamma" value, so we do it the hard way */
198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    infile = fopen("/etc/config/system.glGammaVal", "r");
199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (infile) {
200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        double sgi_gamma;
201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fgets(tmpline, 80, infile);
203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fclose(infile);
204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        sgi_gamma = atof(tmpline);
205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (sgi_gamma > 0.0)
206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            LUT_exponent = 1.0 / sgi_gamma;
207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#elif defined(Macintosh)
209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    LUT_exponent = 1.8 / 2.61;
210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /*
211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (some_mac_function_that_returns_gamma(&mac_gamma))
212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        LUT_exponent = mac_gamma / 2.61;
213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     */
214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    LUT_exponent = 1.0;   /* assume no LUT:  most PCs */
216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */
219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    default_display_exponent = LUT_exponent * CRT_exponent;
220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* If the user has set the SCREEN_GAMMA environment variable as suggested
223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * (somewhat imprecisely) in the libpng documentation, use that; otherwise
224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * use the default value we just calculated.  Either way, the user may
225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * override this via a command-line option. */
226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if ((p = getenv("SCREEN_GAMMA")) != NULL)
228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        display_exponent = atof(p);
229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    else
230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        display_exponent = default_display_exponent;
231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* Now parse the command line for options and the PNG filename. */
234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    while (*++argv && !error) {
236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (!strncmp(*argv, "-display", 2)) {
237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (!*++argv)
238893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                ++error;
239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                displayname = *argv;
241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        } else if (!strncmp(*argv, "-gamma", 2)) {
242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (!*++argv)
243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                ++error;
244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else {
245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                display_exponent = atof(*argv);
246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (display_exponent <= 0.0)
247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ++error;
248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        } else if (!strncmp(*argv, "-bgcolor", 2)) {
250893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (!*++argv)
251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                ++error;
252893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else {
253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                bgstr = *argv;
254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (strlen(bgstr) != 7 || bgstr[0] != '#')
255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ++error;
256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                else
257893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    have_bg = TRUE;
258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        } else {
260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (**argv != '-') {
261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                filename = *argv;
262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (argv[1])   /* shouldn't be any more args after filename */
263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ++error;
264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            } else
265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                ++error;   /* not expecting any other options */
266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!filename)
270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        ++error;
271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
272893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* print usage screen if any errors up to this point */
274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (error) {
276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, "\n%s %s:  %s\n", PROGNAME, VERSION, appname);
277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        readpng_version_info();
278893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, "\n"
279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "Usage:  %s [-display xdpy] [-gamma exp] [-bgcolor bg] file.png\n"
280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "    xdpy\tname of the target X display (e.g., ``hostname:0'')\n"
281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "    exp \ttransfer-function exponent (``gamma'') of the display\n"
282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\t\t  system in floating-point format (e.g., ``%.1f''); equal\n"
283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\t\t  to the product of the lookup-table exponent (varies)\n"
284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\t\t  and the CRT exponent (usually 2.2); must be positive\n"
285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "    bg  \tdesired background color in 7-character hex RGB format\n"
286893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\t\t  (e.g., ``#ff7700'' for orange:  same as HTML colors);\n"
287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\t\t  used with transparent images\n"
288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\nPress Q, Esc or mouse button 1 (within image window, after image\n"
289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "is displayed) to quit.\n"
290893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\n", PROGNAME, default_display_exponent);
291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        exit(1);
292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!(infile = fopen(filename, "rb"))) {
296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, PROGNAME ":  can't open PNG file [%s]\n", filename);
297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        ++error;
298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else {
299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if ((rc = readpng_init(infile, &image_width, &image_height)) != 0) {
300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            switch (rc) {
301893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                case 1:
302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    fprintf(stderr, PROGNAME
303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                      ":  [%s] is not a PNG file: incorrect signature\n",
304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                      filename);
305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    break;
306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                case 2:
307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    fprintf(stderr, PROGNAME
308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                      ":  [%s] has bad IHDR (libpng longjmp)\n", filename);
309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    break;
310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                case 4:
311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    fprintf(stderr, PROGNAME ":  insufficient memory\n");
312893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    break;
313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                default:
314893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    fprintf(stderr, PROGNAME
315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                      ":  unknown readpng_init() error\n");
316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    break;
317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            ++error;
319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        } else {
320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            display = XOpenDisplay(displayname);
321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (!display) {
322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                readpng_cleanup(TRUE);
323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                fprintf(stderr, PROGNAME ":  can't open X display [%s]\n",
324893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  displayname? displayname : "default");
325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                ++error;
326893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
328893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (error)
329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            fclose(infile);
330893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (error) {
334893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, PROGNAME ":  aborting.\n");
335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        exit(2);
336893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* set the title-bar string, but make sure buffer doesn't overflow */
340893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    alen = strlen(appname);
342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    flen = strlen(filename);
343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (alen + flen + 3 > 1023)
344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        sprintf(titlebar, "%s:  ...%s", appname, filename+(alen+flen+6-1023));
345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    else
346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        sprintf(titlebar, "%s:  %s", appname, filename);
347893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* if the user didn't specify a background color on the command line,
350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * check for one in the PNG file--if not, the initialized values of 0
351893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * (black) will be used */
352893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (have_bg) {
354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        unsigned r, g, b;   /* this approach quiets compiler warnings */
355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b);
357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        bg_red   = (uch)r;
358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        bg_green = (uch)g;
359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        bg_blue  = (uch)b;
360893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else if (readpng_get_bgcolor(&bg_red, &bg_green, &bg_blue) > 1) {
361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        readpng_cleanup(TRUE);
362893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, PROGNAME
363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          ":  libpng error while checking for background color\n");
364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        exit(2);
365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
366893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* do the basic X initialization stuff, make the window and fill it
369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * with the background color */
370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (rpng_x_create_window())
372893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        exit(2);
373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* decode the image, all at once */
376893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "calling readpng_get_image()\n"))
378893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    image_data = readpng_get_image(display_exponent, &image_channels,
379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      &image_rowbytes);
380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "done with readpng_get_image()\n"))
381893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
382893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
383893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* done with PNG file, so clean up to minimize memory usage (but do NOT
384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * nuke image_data!) */
385893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
386893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    readpng_cleanup(FALSE);
387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    fclose(infile);
388893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
389893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!image_data) {
390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, PROGNAME ":  unable to decode PNG image\n");
391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        exit(3);
392893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
393893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
395893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* display image (composite with background if requested) */
396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
397893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "calling rpng_x_display_image()\n"))
398893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (rpng_x_display_image()) {
399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        free(image_data);
400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        exit(4);
401893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
402893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "done with rpng_x_display_image()\n"))
403893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
404893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
405893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* wait for the user to tell us when to quit */
406893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
407893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    printf(
408893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      "Done.  Press Q, Esc or mouse button 1 (within image window) to quit.\n");
409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    fflush(stdout);
410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    do
412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XNextEvent(display, &e);
413893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    while (!(e.type == ButtonPress && e.xbutton.button == Button1) &&
414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           !(e.type == KeyPress &&    /*  v--- or 1 for shifted keys */
415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             ((k = XLookupKeysym(&e.xkey, 0)) == XK_q || k == XK_Escape) ));
416893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
417893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
418893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* OK, we're done:  clean up all image and X resources and go away */
419893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    rpng_x_cleanup();
421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
422893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return 0;
423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
427893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int rpng_x_create_window(void)
430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
431893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch *xdata;
432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int need_colormap = FALSE;
433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int screen, pad;
434893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ulg bg_pixel = 0L;
435893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ulg attrmask;
436893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Window root;
437893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XEvent e;
438893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XGCValues gcvalues;
439893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XSetWindowAttributes attr;
440893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XTextProperty windowName, *pWindowName = &windowName;
441893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XTextProperty iconName, *pIconName = &iconName;
442893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XVisualInfo visual_info;
443893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XSizeHints *size_hints;
444893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XWMHints *wm_hints;
445893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XClassHint *class_hints;
446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
447893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
448893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    screen = DefaultScreen(display);
449893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    depth = DisplayPlanes(display, screen);
450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    root = RootWindow(display, screen);
451893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef DEBUG
453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XSynchronize(display, True);
454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
455893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if 0
457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* GRR:  add 8-bit support */
458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (/* depth != 8 && */ depth != 16 && depth != 24 && depth != 32) {
459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr,
460893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "screen depth %d not supported (only 16-, 24- or 32-bit TrueColor)\n",
461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          depth);
462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        return 2;
463893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
464893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XMatchVisualInfo(display, screen, depth,
466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      (depth == 8)? PseudoColor : TrueColor, &visual_info);
467893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    visual = visual_info.visual;
468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
469893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (depth != 16 && depth != 24 && depth != 32) {
470893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int visuals_matched = 0;
471893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        Trace((stderr, "default depth is %d:  checking other visuals\n",
473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          depth))
474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        /* 24-bit first */
476893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        visual_info.screen = screen;
477893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        visual_info.depth = 24;
478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        visual_list = XGetVisualInfo(display,
479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          VisualScreenMask | VisualDepthMask, &visual_info, &visuals_matched);
480893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (visuals_matched == 0) {
481893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* GRR:  add 15-, 16- and 32-bit TrueColor visuals (also DirectColor?) */
482893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            fprintf(stderr, "default screen depth %d not supported, and no"
483893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              " 24-bit visuals found\n", depth);
484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            return 2;
485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
486893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        Trace((stderr, "XGetVisualInfo() returned %d 24-bit visuals\n",
487893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          visuals_matched))
488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        visual = visual_list[0].visual;
489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        depth = visual_list[0].depth;
490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*
491893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        colormap_size = visual_list[0].colormap_size;
492893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        visual_class = visual->class;
493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        visualID = XVisualIDFromVisual(visual);
494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        have_nondefault_visual = TRUE;
496893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        need_colormap = TRUE;
497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else {
498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XMatchVisualInfo(display, screen, depth, TrueColor, &visual_info);
499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        visual = visual_info.visual;
500893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    RMask = visual->red_mask;
504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    GMask = visual->green_mask;
505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    BMask = visual->blue_mask;
506893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
507893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* GRR:  add/check 8-bit support */
508893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (depth == 8 || need_colormap) {
509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        colormap = XCreateColormap(display, root, visual, AllocNone);
510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (!colormap) {
511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            fprintf(stderr, "XCreateColormap() failed\n");
512893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            return 2;
513893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
514893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        have_colormap = TRUE;
515893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
516893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (depth == 15 || depth == 16) {
517893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        RShift = 15 - rpng_x_msb(RMask);    /* these are right-shifts */
518893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        GShift = 15 - rpng_x_msb(GMask);
519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        BShift = 15 - rpng_x_msb(BMask);
520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else if (depth > 16) {
521893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define NO_24BIT_MASKS
522893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef NO_24BIT_MASKS
523893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        RShift = rpng_x_msb(RMask) - 7;     /* these are left-shifts */
524893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        GShift = rpng_x_msb(GMask) - 7;
525893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        BShift = rpng_x_msb(BMask) - 7;
526893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
527893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        RShift = 7 - rpng_x_msb(RMask);     /* these are right-shifts, too */
528893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        GShift = 7 - rpng_x_msb(GMask);
529893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        BShift = 7 - rpng_x_msb(BMask);
530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
531893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
532893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (depth >= 15 && (RShift < 0 || GShift < 0 || BShift < 0)) {
533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, "rpng internal logic error:  negative X shift(s)!\n");
534893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        return 2;
535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
537893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
538893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Finally, create the window.
539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    attr.backing_store = Always;
542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask;
543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    attrmask = CWBackingStore | CWEventMask;
544893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (have_nondefault_visual) {
545893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        attr.colormap = colormap;
546893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        attr.background_pixel = 0;
547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        attr.border_pixel = 1;
548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        attrmask |= CWColormap | CWBackPixel | CWBorderPixel;
549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
550893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    window = XCreateWindow(display, root, 0, 0, image_width, image_height, 0,
552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      depth, InputOutput, visual, attrmask, &attr);
553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (window == None) {
555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, "XCreateWindow() failed\n");
556893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        return 2;
557893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else
558893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        have_window = TRUE;
559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
560893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (depth == 8)
561893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XSetWindowColormap(display, window, colormap);
562893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
563893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!XStringListToTextProperty(&window_name, 1, pWindowName))
564893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        pWindowName = NULL;
565893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!XStringListToTextProperty(&icon_name, 1, pIconName))
566893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        pIconName = NULL;
567893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
568893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* OK if any hints allocation fails; XSetWMProperties() allows NULLs */
569893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
570893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if ((size_hints = XAllocSizeHints()) != NULL) {
571893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        /* window will not be resizable */
572893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        size_hints->flags = PMinSize | PMaxSize;
573893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        size_hints->min_width = size_hints->max_width = (int)image_width;
574893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        size_hints->min_height = size_hints->max_height = (int)image_height;
575893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
577893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if ((wm_hints = XAllocWMHints()) != NULL) {
578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        wm_hints->initial_state = NormalState;
579893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        wm_hints->input = True;
580893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     /* wm_hints->icon_pixmap = icon_pixmap; */
581893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        wm_hints->flags = StateHint | InputHint  /* | IconPixmapHint */ ;
582893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
583893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
584893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if ((class_hints = XAllocClassHint()) != NULL) {
585893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        class_hints->res_name = res_name;
586893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        class_hints->res_class = res_class;
587893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
588893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
589893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XSetWMProperties(display, window, pWindowName, pIconName, NULL, 0,
590893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      size_hints, wm_hints, class_hints);
591893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
592893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* various properties and hints no longer needed; free memory */
593893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (pWindowName)
594893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       XFree(pWindowName->value);
595893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (pIconName)
596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       XFree(pIconName->value);
597893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (size_hints)
598893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XFree(size_hints);
599893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (wm_hints)
600893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       XFree(wm_hints);
601893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (class_hints)
602893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       XFree(class_hints);
603893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
604893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XMapWindow(display, window);
605893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
606893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    gc = XCreateGC(display, window, 0, &gcvalues);
607893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    have_gc = TRUE;
608893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
609893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
610893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Fill window with the specified background color.
611893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
613893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (depth == 24 || depth == 32) {
614893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        bg_pixel = ((ulg)bg_red   << RShift) |
615893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                   ((ulg)bg_green << GShift) |
616893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                   ((ulg)bg_blue  << BShift);
617893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else if (depth == 16) {
618893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        bg_pixel = ((((ulg)bg_red   << 8) >> RShift) & RMask) |
619893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                   ((((ulg)bg_green << 8) >> GShift) & GMask) |
620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                   ((((ulg)bg_blue  << 8) >> BShift) & BMask);
621893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else /* depth == 8 */ {
622893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
623893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        /* GRR:  add 8-bit support */
624893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
625893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
626893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
627893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XSetForeground(display, gc, bg_pixel);
628893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XFillRectangle(display, window, gc, 0, 0, image_width, image_height);
629893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
630893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
631893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Wait for first Expose event to do any drawing, then flush.
632893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
633893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
634893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    do
635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XNextEvent(display, &e);
636893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    while (e.type != Expose || e.xexpose.count);
637893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
638893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XFlush(display);
639893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
640893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
641893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Allocate memory for the X- and display-specific version of the image.
642893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
643893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
644893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (depth == 24 || depth == 32) {
645893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        xdata = (uch *)malloc(4*image_width*image_height);
646893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        pad = 32;
647893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else if (depth == 16) {
648893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        xdata = (uch *)malloc(2*image_width*image_height);
649893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        pad = 16;
650893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else /* depth == 8 */ {
651893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        xdata = (uch *)malloc(image_width*image_height);
652893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        pad = 8;
653893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
654893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
655893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!xdata) {
656893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, PROGNAME ":  unable to allocate image memory\n");
657893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        return 4;
658893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
659893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
660893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ximage = XCreateImage(display, visual, depth, ZPixmap, 0,
661893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      (char *)xdata, image_width, image_height, pad, 0);
662893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
663893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!ximage) {
664893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, PROGNAME ":  XCreateImage() failed\n");
665893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        free(xdata);
666893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        return 3;
667893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
668893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
669893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* to avoid testing the byte order every pixel (or doubling the size of
670893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * the drawing routine with a giant if-test), we arbitrarily set the byte
671893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * order to MSBFirst and let Xlib worry about inverting things on little-
672893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * endian machines (like Linux/x86, old VAXen, etc.)--this is not the most
673893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * efficient approach (the giant if-test would be better), but in the
674893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * interest of clarity, we take the easy way out... */
675893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
676893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ximage->byte_order = MSBFirst;
677893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
678893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return 0;
679893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
680893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} /* end function rpng_x_create_window() */
681893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
682893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
683893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
684893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
685893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
686893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int rpng_x_display_image(void)
687893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
688893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch *src;
689893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    char *dest;
690893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch r, g, b, a;
691893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ulg i, row, lastrow = 0;
692893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ulg pixel;
693893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int ximage_rowbytes = ximage->bytes_per_line;
694893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*  int bpp = ximage->bits_per_pixel;  */
695893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
696893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
697893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "beginning display loop (image_channels == %d)\n",
698893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      image_channels))
699893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "   (width = %ld, rowbytes = %ld, ximage_rowbytes = %d)\n",
700893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      image_width, image_rowbytes, ximage_rowbytes))
701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "   (bpp = %d)\n", ximage->bits_per_pixel))
702893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "   (byte_order = %s)\n", ximage->byte_order == MSBFirst?
703893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      "MSBFirst" : (ximage->byte_order == LSBFirst? "LSBFirst" : "unknown")))
704893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
705893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (depth == 24 || depth == 32) {
706893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        ulg red, green, blue;
707893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
708893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (lastrow = row = 0;  row < image_height;  ++row) {
709893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            src = image_data + row*image_rowbytes;
710893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            dest = ximage->data + row*ximage_rowbytes;
711893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (image_channels == 3) {
712893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                for (i = image_width;  i > 0;  --i) {
713893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    red   = *src++;
714893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    green = *src++;
715893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    blue  = *src++;
716893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef NO_24BIT_MASKS
717893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    pixel = (red   << RShift) |
718893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            (green << GShift) |
719893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            (blue  << BShift);
720893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    /* recall that we set ximage->byte_order = MSBFirst above */
721893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    /* GRR BUG:  this assumes bpp == 32, but may be 24: */
722893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >> 24) & 0xff);
723893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >> 16) & 0xff);
724893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >>  8) & 0xff);
725893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)( pixel        & 0xff);
726893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
727893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    red   = (RShift < 0)? red   << (-RShift) : red   >> RShift;
728893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    green = (GShift < 0)? green << (-GShift) : green >> GShift;
729893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    blue  = (BShift < 0)? blue  << (-BShift) : blue  >> BShift;
730893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    pixel = (red & RMask) | (green & GMask) | (blue & BMask);
731893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    /* recall that we set ximage->byte_order = MSBFirst above */
732893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >> 24) & 0xff);
733893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >> 16) & 0xff);
734893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >>  8) & 0xff);
735893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)( pixel        & 0xff);
736893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
737893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
738893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            } else /* if (image_channels == 4) */ {
739893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                for (i = image_width;  i > 0;  --i) {
740893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    r = *src++;
741893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    g = *src++;
742893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    b = *src++;
743893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    a = *src++;
744893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    if (a == 255) {
745893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        red   = r;
746893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        green = g;
747893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        blue  = b;
748893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    } else if (a == 0) {
749893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        red   = bg_red;
750893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        green = bg_green;
751893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        blue  = bg_blue;
752893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    } else {
753893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        /* this macro (from png.h) composites the foreground
754893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                         * and background values and puts the result into the
755893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                         * first argument */
756893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        alpha_composite(red,   r, a, bg_red);
757893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        alpha_composite(green, g, a, bg_green);
758893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        alpha_composite(blue,  b, a, bg_blue);
759893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    }
760893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    pixel = (red   << RShift) |
761893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            (green << GShift) |
762893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            (blue  << BShift);
763893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    /* recall that we set ximage->byte_order = MSBFirst above */
764893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >> 24) & 0xff);
765893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >> 16) & 0xff);
766893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >>  8) & 0xff);
767893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)( pixel        & 0xff);
768893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
769893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
770893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            /* display after every 16 lines */
771893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (((row+1) & 0xf) == 0) {
772893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
773893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (int)lastrow, image_width, 16);
774893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                XFlush(display);
775893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                lastrow = row + 1;
776893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
777893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
778893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
779893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else if (depth == 16) {
780893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        ush red, green, blue;
781893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
782893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (lastrow = row = 0;  row < image_height;  ++row) {
783893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            src = image_data + row*image_rowbytes;
784893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            dest = ximage->data + row*ximage_rowbytes;
785893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (image_channels == 3) {
786893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                for (i = image_width;  i > 0;  --i) {
787893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    red   = ((ush)(*src) << 8);
788893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ++src;
789893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    green = ((ush)(*src) << 8);
790893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ++src;
791893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    blue  = ((ush)(*src) << 8);
792893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ++src;
793893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    pixel = ((red   >> RShift) & RMask) |
794893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            ((green >> GShift) & GMask) |
795893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            ((blue  >> BShift) & BMask);
796893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    /* recall that we set ximage->byte_order = MSBFirst above */
797893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >>  8) & 0xff);
798893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)( pixel        & 0xff);
799893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
800893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            } else /* if (image_channels == 4) */ {
801893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                for (i = image_width;  i > 0;  --i) {
802893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    r = *src++;
803893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    g = *src++;
804893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    b = *src++;
805893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    a = *src++;
806893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    if (a == 255) {
807893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        red   = ((ush)r << 8);
808893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        green = ((ush)g << 8);
809893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        blue  = ((ush)b << 8);
810893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    } else if (a == 0) {
811893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        red   = ((ush)bg_red   << 8);
812893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        green = ((ush)bg_green << 8);
813893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        blue  = ((ush)bg_blue  << 8);
814893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    } else {
815893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        /* this macro (from png.h) composites the foreground
816893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                         * and background values and puts the result back into
817893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                         * the first argument (== fg byte here:  safe) */
818893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        alpha_composite(r, r, a, bg_red);
819893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        alpha_composite(g, g, a, bg_green);
820893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        alpha_composite(b, b, a, bg_blue);
821893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        red   = ((ush)r << 8);
822893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        green = ((ush)g << 8);
823893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        blue  = ((ush)b << 8);
824893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    }
825893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    pixel = ((red   >> RShift) & RMask) |
826893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            ((green >> GShift) & GMask) |
827893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            ((blue  >> BShift) & BMask);
828893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    /* recall that we set ximage->byte_order = MSBFirst above */
829893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >>  8) & 0xff);
830893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)( pixel        & 0xff);
831893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
832893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
833893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            /* display after every 16 lines */
834893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (((row+1) & 0xf) == 0) {
835893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
836893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (int)lastrow, image_width, 16);
837893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                XFlush(display);
838893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                lastrow = row + 1;
839893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
840893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
841893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
842893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else /* depth == 8 */ {
843893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
844893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        /* GRR:  add 8-bit support */
845893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
846893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
847893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
848893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "calling final XPutImage()\n"))
849893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (lastrow < image_height) {
850893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
851893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          (int)lastrow, image_width, image_height-lastrow);
852893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XFlush(display);
853893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
854893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
855893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return 0;
856893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
857893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
858893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
859893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
860893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
861893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void rpng_x_cleanup(void)
862893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
863893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (image_data) {
864893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        free(image_data);
865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        image_data = NULL;
866893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
867893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
868893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (ximage) {
869893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (ximage->data) {
870893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            free(ximage->data);           /* we allocated it, so we free it */
871893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            ximage->data = (char *)NULL;  /*  instead of XDestroyImage() */
872893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
873893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XDestroyImage(ximage);
874893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        ximage = NULL;
875893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
876893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
877893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (have_gc)
878893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XFreeGC(display, gc);
879893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
880893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (have_window)
881893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XDestroyWindow(display, window);
882893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
883893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (have_colormap)
884893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XFreeColormap(display, colormap);
885893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
886893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (have_nondefault_visual)
887893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XFree(visual_list);
888893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
889893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
890893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
891893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
892893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
893893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
894893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int rpng_x_msb(ulg u32val)
895893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
896893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int i;
897893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
898893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    for (i = 31;  i >= 0;  --i) {
899893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (u32val & 0x80000000L)
900893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
901893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        u32val <<= 1;
902893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
903893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return i;
904893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
905