2
ACfax - Fax reception with X11-interface for amateur radio
3
Copyright (C) 1995-1998 Andreas Czechanowski, DL4SDC
5
This program is free software; you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation; either version 2 of the License, or
8
(at your option) any later version.
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
GNU General Public License for more details.
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software Foundation,
17
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
andreas.czechanowski@ins.uni-stuttgart.de
23
* x_image.c - XImage and colormap allocation functions
31
#include <X11/Intrinsic.h>
35
unsigned long coltab[256]; /* mapping table grayscale->pixel-value */
36
char cused[256]; /* table indicating used pixel-values */
37
Display *dpy = NULL; /* X-display used */
38
Screen *scrn = NULL; /* Screen of display */
39
Visual *visl = NULL; /* Visual of screen to use */
40
int depth = -1; /* depth of screen (# of planes) */
41
Colormap icmap; /* the colormap to use */
42
XImage *horimag = NULL; /* intermediate-storage for horizontal scan */
43
XImage *verimag = NULL; /* intermediate-storage for vertical scan */
44
XVisualInfo visinfo; /* Visual-info-structure (from Xutil.h) */
45
unsigned long r_mask; /* bit mask bits (truecolor) for red */
46
unsigned long g_mask; /* bit mask bits (truecolor) for green */
47
unsigned long b_mask; /* bit mask bits (truecolor) for blue */
48
int r_shift; /* position of LSB in r_mask */
49
int g_shift; /* position of LSB in g_mask */
50
int b_shift; /* position of LSB in b_mask */
51
int r_bits; /* count of significant bits in r_mask */
52
int g_bits; /* count of significant bits in g_mask */
53
int b_bits; /* count of significant bits in b_mask */
56
* get some global X11-variables and resources from the passed Widget
58
void get_globals(Widget toplevel)
61
dpy = XtDisplay(toplevel);
63
scrn = XtScreen(toplevel);
65
depth = DefaultDepthOfScreen(scrn);
67
visl = DefaultVisualOfScreen(scrn);
69
if (!(XMatchVisualInfo(dpy, XScreenNumberOfScreen(scrn), depth,
70
PseudoColor, &visinfo))) {
71
fprintf(stderr, "cannot get PseudoColor-visual with depth %d !\n", depth);
74
visl = visinfo.visual;
80
* create two XImages as "transportation storage" between the raw-resulution
81
* picture and the canvas-widget's pixmap (one horizontal stripe with
82
* DEFHEIGHT lines, and one vertical stripe with DEFWIDTH columns).
83
* If called more than once, the old
84
* XImages are Destroyes and new ones are created with the given size.
86
void create_images(Widget toplevel, Dimension wid, Dimension hei)
88
get_globals(toplevel);
89
fprintf(stderr, "creating XImage for %d x %d pixels\n", wid, hei);
90
/* delete old images and their data (when image is resized) */
92
XDestroyImage(horimag);
94
XDestroyImage(verimag);
95
horimag = XCreateImage(dpy, visl, depth, ZPixmap, 0, NULL,
96
wid, DEFHEIGHT, 32, 0);
97
verimag = XCreateImage(dpy, visl, depth, ZPixmap, 0, NULL,
98
DEFWIDTH, hei, 32, 0);
99
if (!(horimag) || !(verimag)) {
100
fprintf(stderr,"cannot allocate Ximages !\n");
103
/* allocate data for the XImages (not done by XCreateImage !) */
104
horimag->data = (char *)XtMalloc(DEFHEIGHT * horimag->bytes_per_line);
105
verimag->data = (char *)XtMalloc(hei * verimag->bytes_per_line);
106
if (!(horimag->data) || !(verimag->data)) {
107
fprintf(stderr,"cannot allocate space for Ximage !\n");
113
* free the space allocated by the two XImages
115
void destroy_images(void)
118
XDestroyImage(horimag);
120
XDestroyImage(verimag);
124
* allocate a new colormap. This is needed for PseudoColor visuals
125
* of depth 8. For truecolor displays, nothing is to be done here.
127
void alloc_cmap(Widget toplevel, Pixel *respix, unsigned nrespix)
131
static int cmap_created = 0;
133
XVisualInfo vTemplate;
134
XVisualInfo *visuals;
136
unsigned long tmpmask;
138
get_globals(toplevel);
143
rootcmap = DefaultColormapOfScreen(scrn);
145
icmap = XCreateColormap(dpy, XtWindow(toplevel), visl, AllocAll);
147
/* XAllocColorCells(dpy, icmap, True, planes, 0, pixels, 216); */
148
/* copy the first 16 colors from the root-colormap, and also copy
149
the colors needed for our widgets */
150
for (i=0; i<(1 << depth); i++)
152
for (i=0; i<nrespix; i++)
155
fprintf(stderr, "respix[%d] = %u\n", i, (unsigned) respix[i]);
157
if (respix[i] > ((1 << depth) - 1)) respix[i] = 0;
158
col.pixel = respix[i];
159
cused[respix[i]] = 1;
160
XQueryColor(dpy, rootcmap, &col);
161
XStoreColor(dpy, icmap, &col);
163
/* now, we can use the rest of the colors for the
164
grayscale or 6x6x6 colormap, but this is done
165
in fill_cmap_col and fill_cmap_gray */
169
/* we want a visual with the depth of our screen : */
170
vTemplate.screen = XScreenNumberOfScreen(scrn);
171
vTemplate.depth = DefaultDepth(dpy, vTemplate.screen);
173
visuals = XGetVisualInfo(dpy, VisualScreenMask | VisualDepthMask,
174
&vTemplate, &nvisuals);
177
fprintf(stderr, "cannot find visual matching default depth %d\n",
181
/* copy first visual info to own location */
182
visinfo = visuals[0];
183
/* discard the array from XGetVisualInfo() */
186
/* determine the bit positions and count of significant bits
187
* for red, green and blue, store it in *_shift and *_bits */
188
r_mask = visinfo.red_mask;
189
g_mask = visinfo.green_mask;
190
b_mask = visinfo.blue_mask;
191
if (r_mask == 0 || g_mask == 0 || b_mask == 0)
193
fprintf(stderr, "one of the color masks is zero : %08lx %08lx %08lx\n",
194
r_mask, g_mask, b_mask);
198
/* determine number of bits and position of mask for every color */
199
r_shift = g_shift = b_shift = 0;
200
r_bits = g_bits = b_bits = 0;
203
while ((tmpmask & 1) == 0)
208
while ((tmpmask & 1) == 1)
215
while ((tmpmask & 1) == 0)
220
while ((tmpmask & 1) == 1)
227
while ((tmpmask & 1) == 0)
232
while ((tmpmask & 1) == 1)
239
fprintf (stderr, "Cannot handle StaticGray visual - abort\n");
243
fprintf (stderr, "Cannot handle GrayScale visual - abort\n");
247
fprintf (stderr, "unknown visual type %x - abort\n", visl->class);
254
* fill the colormap with a 6x6x6 color-cube.
255
* when flip is set, the green and blue indexing is exchanged, and rotate
256
* defines the order in which the colors are indexed.
257
* The array coltab is filled with a lookup-table color_value -> pixel_index.
259
void fill_cmap_col(int invert, int flip, int rotate)
262
unsigned ixr, ixg, ixb;
266
fprintf(stderr, "filling colormap with 6x6x6 cube\n");
267
col.flags = DoRed | DoGreen | DoBlue;
271
ixg = (flip) ? 0 : 2;
272
ixb = (flip) ? 2 : 0;
276
ixg = (flip) ? 1 : 0;
277
ixb = (flip) ? 0 : 1;
282
ixg = (flip) ? 2 : 1;
283
ixb = (flip) ? 1 : 2;
286
for (cm[0]=0; cm[0]<6; cm[0]++)
287
for (cm[1]=0; cm[1]<6; cm[1]++)
288
for (cm[2]=0; cm[2]<6; cm[2]++) {
289
while ((cused[i]) && i < 256) i++;
291
fprintf(stderr,"cannot assign all required colors !\n");
296
col.red = 65535 - 9362 * (cm[ixr] + 1);
297
col.green = 65535 - 9362 * (cm[ixg] + 1);
298
col.blue = 65535 - 9362 * (cm[ixb] + 1);
300
col.red = 9362 * (cm[ixr] + 1);
301
col.green = 9362 * (cm[ixg] + 1);
302
col.blue = 9362 * (cm[ixb] + 1);
304
XStoreColor(dpy, icmap, &col);
305
coltab[cm[0]+6*cm[1]+36*cm[2]] = i;
311
* fill the colormap with a grayscale of 64 steps (should be good enough).
312
* The array coltab is filled with a lookup-table gray_value -> pixel_index.
314
void fill_cmap_gray(int invert)
321
fprintf(stderr, "filling colormap with grayscale\n");
326
col.flags = DoRed | DoGreen | DoBlue;
329
while ((cused[i]) && i < 256) i++;
332
fprintf(stderr,"cannot assign all required grayscales !\n");
336
yv = (invert) ? 63 - g : g;
337
col.red = col.green = col.blue = 1040.2 * yv;
338
XStoreColor(dpy, icmap, &col);
345
/* allocate a translation table grayscale -> truecolor_value */
348
yv = (invert) ? 63 - g : g;
349
cval = (((1 << r_bits) - 1) * yv / 63) << r_shift;
350
cval += (((1 << g_bits) - 1) * yv / 63) << g_shift;
351
cval += (((1 << b_bits) - 1) * yv / 63) << b_shift;