1 /*
2 * xwin.c --
3 *
4 * FIXME: This file needs a description here.
5 *
6 * Copyright (c) 1996-2002 The Regents of the University of California.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 * A. Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 * B. Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution.
17 * C. Neither the names of the copyright holders nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
22 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #define HAVE_SHM
35
36 #include <stdio.h>
37 #include <signal.h>
38 #include <sys/param.h>
39 #include <sys/ipc.h>
40 #ifdef HAVE_SHM
41 #include <sys/shm.h>
42 #endif
43 #include <X11/X.h>
44 #include <X11/Xlib.h>
45 #include <X11/Xutil.h>
46 #ifdef HAVE_SHM
47 #include <X11/extensions/XShm.h>
48 #endif
49
50 static Display *dpy;
51
52 struct wininfo {
53 Window win;
54 Visual *visual;/* pointer to visual */
55 XVisualInfo vinfo; /* info on visual (or template) */
56 GC gc; /* graphics context */
57 Colormap cmap; /* colormap */
58 int x,y; /* origin relative to parent */
59 };
60
61 Window
62 createXwindow(int w, int h, char *wname, char *iname, struct wininfo *info)
63 {
64 XVisualInfo *vList;
65 int visualsMatched;
66 XSizeHints size_hints;
67 int screen;
68 u_int border_width = 2;
69 Window win, root;
70 XSetWindowAttributes attr;
71
72 /* Get screen size from display structure macro */
73 info->vinfo.screen = screen = DefaultScreen(dpy);
74 root = DefaultRootWindow(dpy);
75
76 #ifdef notdef
77 if (info->visual == 0) {
78 vList = XGetVisualInfo(dpy, VisualScreenMask|VisualDepthMask
79 | VisualClassMask,
80 &info->vinfo, &visualsMatched);
81 if (visualsMatched == 0) {
82 fprintf(stderr, "cannot find suitable visual\n");
83 exit(-1);
84 }
85 info->visual = vList[0].visual;
86 /* store info about Visual */
87 info->vinfo = vList[0];
88
89 /* each visual requires a different colormap */
90 info->cmap = XCreateColormap(dpy, root, info->visual,
91 AllocNone);
92 }
93 #else
94 info->visual = DefaultVisual(dpy, DefaultScreen(dpy));
95 info->cmap = DefaultColormap(dpy, DefaultScreen(dpy));
96 #endif
97 attr.colormap = info->cmap;
98 attr.event_mask = VisibilityChangeMask;
99 attr.backing_store = Always;
100 attr.border_pixel = BlackPixel(dpy, screen);
101 attr.background_pixel = BlackPixel(dpy, screen);
102
103 win = XCreateWindow(dpy, root, info->x, info->y, w, h,
104 border_width, info->vinfo.depth, InputOutput,
105 info->visual,
106 CWColormap | CWBorderPixel | CWBackPixel |
107 CWEventMask | CWBackingStore,
108 &attr);
109
110 /* Initialize size hint property for window manager */
111 size_hints.flags = PSize;
112 size_hints.width = w;
113 size_hints.height = h;
114 if (info->x >= 0)
115 size_hints.x = info->x;
116 if (info->y >= 0)
117 size_hints.y = info->y;
118 size_hints.flags |= USPosition;
119
120 /* Set properties for window manager (always before mapping) */
121 XSetStandardProperties(dpy, win, wname, iname, None,
122 (char **) 0, 0, &size_hints);
123
124 if (info->gc == 0)
125 info->gc = XCreateGC(dpy, win, (u_long)0, (XGCValues *)0);
126
127 XMapWindow(dpy, win);
128 /*
129 * override window manager if it doesn't follow hints
130 * the standard says we're not supposed to do this!
131 */
132 XResizeWindow(dpy, win, w, h);
133 XFlush(dpy);
134 info->win = win;
135 for (;;) {
136 XEvent e;
137 XNextEvent(dpy, &e);
138 if (e.type == VisibilityNotify)
139 break;
140 }
141 return (win);
142 }
143
144 struct wininfo wi;
145 XImage *image;
146 u_char *ximage_data;
147 int ximage_width;
148 int ximage_height;
149 #ifdef HAVE_SHM
150 XShmSegmentInfo si;
151 #endif
152
153 extern int noshm;
154
155 makewin(int width, int height)
156 {
157 if (dpy == 0) {
158 dpy = XOpenDisplay(0);
159 if (dpy == 0) {
160 fprintf(stderr, "cannot open display\n");
161 exit(1);
162 }
163 }
164 wi.vinfo.class = PseudoColor;
165 wi.vinfo.depth = 8;
166 wi.x = 0;
167 wi.y = 0;
168 wi.win = createXwindow(width, height,
169 "dvic", "dvic",
170 &wi);
171
172 image = XCreateImage(dpy, wi.visual, 8,
173 ZPixmap, 0, (char*)ximage_data,
174 width, height, 8, 0);
175 #ifdef HAVE_SHM
176 if (noshm)
177 #endif
178 ximage_data = (u_char*)malloc(width * height);
179 #ifdef HAVE_SHM
180 else {
181 si.shmid = shmget(IPC_PRIVATE, width * height,
182 IPC_CREAT|0777);
183 ximage_data = (u_char *)shmat(si.shmid, 0, 0);
184 if (ximage_data == (u_char*)-1) {
185 perror("shmat");
186 exit(1);
187 }
188 si.shmaddr = (char*)ximage_data;
189 si.readOnly = 1;
190 XShmAttach(dpy, &si);
191 image->obdata = (char*)&si;
192 }
193 #endif
194 image->data = (char*)ximage_data;
195 ximage_width = width;
196 ximage_height = height;
197 }
198
199 putrawimage()
200 {
201 XSync(dpy, 0);
202 #ifdef HAVE_SHM
203 if (!noshm)
204 XShmPutImage(dpy, wi.win, wi.gc, image,
205 0, 0, 0, 0,
206 ximage_width, ximage_height, 0);
207 else
208 #endif
209 XPutImage(dpy, wi.win, wi.gc, image,
210 0, 0, 0, 0,
211 ximage_width, ximage_height);
212 XFlush(dpy);
213 }
214
215 int
216 pixscale(double d)
217 {
218 if (d < 0)
219 return (0);
220 if (d > 255)
221 return (255 << 8);
222 return ((int)d << 8);
223 }
224
225 /*FIXME*/
226 #ifdef __alpha
227 #define u_long u_int
228 #endif
229
230 static u_long color_dither[16] =
231 { 0x180a00, 0x080010, 0x1c0804, 0x0c0214,
232 0x060618, 0x160c08, 0x02041c, 0x120e0c,
233 0x1e0906, 0x0e0316, 0x1a0b02, 0x0a0112,
234 0x00051e, 0x100f0e, 0x04071a, 0x140d0a };
235
236 #define COLORDITHER(l, c, base, d) \
237 { c = (base) + (d); \
238 c = ((c>>9) & 0x7c00) + ((c>>6) & 0x3e0) + ((c>>3) & 0x1f); \
239 c = (l)[c]; }
240
241 extern u_long yuv2rgb[65536], color_lut[32768];
242 u_long yuv2rgb[65536], grey_lut[256], color_lut[32768];
243 #define GREY_LEVELS 32
244
245 /*FIXME*/
246 #ifdef sun
247 #define LITTLEENDIAN 0
248 #else
249 #define LITTLEENDIAN 1
250 #endif
251 int color_ok;
252
253 #define YUVLIM(x) (((x) < 0) ? 0 : ((x) > 127) ? 127 : (x))
254
255 void
256 init_color_cube()
257 {
258 int i, screen, r_shift, g_shift, b_shift;
259 int r, g, b, r0, g0, b0, y, u, v, u0, v0;
260 int colmap;
261 XVisualInfo visinfo;
262 XColor color;
263 u_long small_lut[128], red_lut[128], green_lut[128];
264 u_long blue_lut[128];
265 int screenDepth = 8;/*FIXME*/
266
267 screen = DefaultScreen(dpy);
268 colmap = XDefaultColormap(dpy, screen);/*FIXME*/
269 #ifdef notdef
270 if (DefaultDepth(dpy, screen) == 24) {
271 screenDepth = 24;
272 visual = DefaultVisual(dpy, screen);
273 (void) XMatchVisualInfo(dpy, screen, 24, visual->class, &visinfo);
274 colmap = XDefaultColormap(dpy, screen);
275 } else if (XMatchVisualInfo(dpy, screen, 24, TrueColor, &visinfo)) {
276 Tk_MakeWindowExist(tkMainWin);
277 screenDepth = 24;
278 visual = visinfo.visual;
279 colmap = XCreateColormap(dpy, Tk_WindowId(tkMainWin), visual,
280 AllocNone);
281 } else if (XMatchVisualInfo(dpy, screen, 24, DirectColor, &visinfo)) {
282 Tk_MakeWindowExist(tkMainWin);
283 screenDepth = 24;
284 visual = visinfo.visual;
285 colmap = XCreateColormap(dpy, Tk_WindowId(tkMainWin), visual,
286 AllocNone);
287 } else {
288 screenDepth = DefaultDepth(dpy, screen);
289 visual = DefaultVisual(dpy, screen);
290 colmap = XDefaultColormap(dpy, screen);
291 }
292 #endif
293 if (screenDepth == 1) {
294 /*FIXME*/
295 } else if ((screenDepth == 8) || (screenDepth == 16)) {
296 for (i = 1; i <= GREY_LEVELS; i++) {
297 color.red = color.green = color.blue =
298 i * 65536/GREY_LEVELS - 1;
299 color.flags = DoRed | DoGreen | DoBlue;
300 if (XAllocColor(dpy, colmap, &color) == 0) {
301 fprintf(stderr, "cannot allocate greymap\n");
302 exit(1);
303 }
304 if (LITTLEENDIAN && (screenDepth <= 16))
305 color.pixel <<= (32-screenDepth);
306 grey_lut[i] = color.pixel;
307 }
308 grey_lut[0] = grey_lut[1];
309 for (i = GREY_LEVELS + 1; i < 2*GREY_LEVELS; i++)
310 grey_lut[i] = grey_lut[GREY_LEVELS];
311
312 i = 0;
313 for (b=0; b<4; b++) {
314 for (g=0; g<8; g++) {
315 for (r=0; r<4; r++) {
316 color.red = r * 16384 + 16383;
317 color.green = g * 8192 + 8191;
318 color.blue = b * 16384 + 16383;
319 color.flags = DoRed | DoGreen | DoBlue;
320 if (XAllocColor(dpy, colmap, &color) == 0) {
321 if (screenDepth < 24)
322 XFreeColors(dpy, colmap, small_lut, i, 0);
323 fprintf(stderr, "Can't allocate color cube!\n");
324 color_ok = 0;
325 return;
326 } else {
327 if (LITTLEENDIAN && (screenDepth <= 16))
328 color.pixel <<= (32-screenDepth);
329 small_lut[i++] = color.pixel;
330 }
331 }
332 }
333 }
334
335 i = 0;
336 for (b=0; b<32; b++) {
337 b0 = (b < 4) ? 0 : (b < 16) ? b/4-1 : 3;
338 for (g=0; g<32; g++) {
339 g0 = (g < 2) ? 0 : (g < 16) ? g/2-1 : 7;
340 for (r=0; r<32; r++) {
341 r0 = (r < 4) ? 0 : (r < 16) ? r/4-1 : 3;
342 color_lut[i++] = small_lut[b0*32+g0*4+r0];
343 }
344 }
345 }
346
347 i = 0;
348 for (u=0; u<128; u+=4) {
349 for (v=0; v<128; v+=4) {
350 for (y=0; y<128; y+=2) {
351 u0 = (u < 64) ? u : (u-128);
352 v0 = (v < 64) ? v : (v-128);
353 r = y + 11*v0/8;
354 g = y - 11*u0/32 -45*v0/64;
355 b = y + 111*u0/64;
356 yuv2rgb[i++] = (YUVLIM(b)<<16) + (YUVLIM(g)<<8) + YUVLIM(r);
357 }
358 }
359 }
360 color_ok = 1;
361 } else if ((screenDepth == 24) || (screenDepth == 32)) {
362 for (i=0; i<128; i++) {
363 color.red = color.green = color.blue = i*512 + 256;
364 color.flags = DoRed | DoGreen | DoBlue;
365 if (XAllocColor(dpy, colmap, &color) == 0) {
366 fprintf(stderr, "Can't allocate colors!\n");
367 exit(1);
368 }
369 grey_lut[2*i] = grey_lut[2*i+1] = color.pixel;
370 red_lut[i] = color.pixel & visinfo.red_mask;
371 green_lut[i] = color.pixel & visinfo.green_mask;
372 blue_lut[i] = color.pixel & visinfo.blue_mask;
373 }
374
375 i = 0;
376 for (u=2; u<128; u+=4) {
377 for (v=2; v<128; v+=4) {
378 for (y=1; y<128; y+=2) {
379 u0 = (u < 64) ? u : (u-128);
380 v0 = (v < 64) ? v : (v-128);
381 r = y + 11*v0/8;
382 g = y - 11*u0/32 -45*v0/64;
383 b = y + 111*u0/64;
384 yuv2rgb[i++] = red_lut[YUVLIM(r)] +
385 green_lut[YUVLIM(g)] +
386 blue_lut[YUVLIM(b)];
387 }
388 }
389 }
390 color_ok = 1;
391 } else {
392 fprintf(stderr, "Can't handle this type of display.\n");
393 exit(1);
394 }
395 }
396
397 void
398 rf_dither_scale(u_long *xip, u_char *yp, u_char* up, u_char *vp,
399 int scalebits)
400 {
401 register int w, z, yy;
402 register int scaler = 1 << scalebits;
403 #ifdef notdef
404 const int width = image->width;/*FIXME*/
405 const int height = image->height;
406 #else
407 const int width = 320;/*FIXME*/
408 int height = 232;
409 #endif
410
411 register u_char y0, y1, y2;
412 register u_short uv;
413 register u_long *cd=color_dither, *lut=color_lut, c, base, out;
414
415 #ifdef notdef
416 yp = &vidPtr->image->y_data[y*imagewidth+x];
417 uvp = (u_short *) &vidPtr->image->uv_data[y*imagewidth+x];
418 xip = &((u_long *)vidPtr->ximage->data)
419 [(y >> scalebits)*ximagewidth + (x >> (scalebits+2))];
420 #endif
421 z = 0;
422 while (height > 0) {
423 for (w = width; w > 0; w -= 8*scaler) {
424 uv = ((up[0] - 128) & 0xf8) << 8;
425 uv |= ((vp[0] - 128) & 0xf8) << 3;
426 base = yuv2rgb[uv + (yp[0] >> 2)];
427 COLORDITHER(lut, out, base, cd[z]);
428
429 uv = ((up[scaler/2] - 128) & 0xf8) << 8;
430 uv |= ((vp[scaler/2] - 128) & 0xf8) << 3;
431 base = yuv2rgb[uv + (yp[scaler] >> 2)];
432 COLORDITHER(lut, c, base, cd[z+1]);
433 out = (out >> 8) + c;
434
435 yp += 2*scaler;
436 up += scaler;
437 vp += scaler;
438
439 uv = ((up[0] - 128) & 0xf8) << 8;
440 uv |= ((vp[0] - 128) & 0xf8) << 3;
441 base = yuv2rgb[uv + (yp[0] >> 2)];
442 COLORDITHER(lut, c, base, cd[z+2]);
443 out = (out >> 8) + c;
444
445 uv = ((up[scaler/2] - 128) & 0xf8) << 8;
446 uv |= ((vp[scaler/2] - 128) & 0xf8) << 3;
447 base = yuv2rgb[uv + (yp[scaler] >> 2)];
448 COLORDITHER(lut, c, base, cd[z+3]);
449 xip[0] = (out >> 8) + c;
450
451 yp += 2*scaler;
452 up += scaler;
453 vp += scaler;
454
455 uv = ((up[0] - 128) & 0xf8) << 8;
456 uv |= ((vp[0] - 128) & 0xf8) << 3;
457 base = yuv2rgb[uv + (yp[0] >> 2)];
458 COLORDITHER(lut, out, base, cd[z]);
459
460 uv = ((up[scaler/2] - 128) & 0xf8) << 8;
461 uv |= ((vp[scaler/2] - 128) & 0xf8) << 3;
462 base = yuv2rgb[uv + (yp[scaler] >> 2)];
463 COLORDITHER(lut, c, base, cd[z+1]);
464 out = (out >> 8) + c;
465
466 yp += 2*scaler;
467 up += scaler;
468 vp += scaler;
469
470 uv = ((up[0] - 128) & 0xf8) << 8;
471 uv |= ((vp[0] - 128) & 0xf8) << 3;
472 base = yuv2rgb[uv + (yp[0] >> 2)];
473 COLORDITHER(lut, c, base, cd[z+2]);
474 out = (out >> 8) + c;
475
476 uv = ((up[scaler/2] - 128) & 0xf8) << 8;
477 uv |= ((vp[scaler/2] - 128) & 0xf8) << 3;
478 base = yuv2rgb[uv + (yp[scaler] >> 2)];
479 COLORDITHER(lut, c, base, cd[z+3]);
480 xip[1] = (out >> 8) + c;
481
482 yp += 2*scaler;
483 up += scaler;
484 vp += scaler;
485 xip += 2;
486 }
487 yp += width << (scalebits - 1);
488 up += (width << (scalebits - 1)) / 2;
489 z = (z + 4) & 0xf;
490 height -= scaler;
491 }
492 }
493
494 void
495 rf_dither(u_long *xip, u_char *yp, u_char* up, u_char *vp, int len)
496 {
497 register int w, z, yy;
498
499 #ifdef notdef
500 int imagewidth = 320;/*FIXME*/
501 int ximagewidth = image->bytes_per_line/4;
502 #endif
503 const int width = image->width;/*FIXME*/
504
505 register u_char y0, y1, y2;
506 register u_short uv;
507 register u_long *cd=color_dither, *lut=color_lut, c, base, out;
508
509 z = 0;
510
511 w = width;
512 for (; len >= 0; len -= 8) {
513 uv = ((up[0] - 128) & 0xf8) << 8;
514 uv |= ((vp[0] - 128) & 0xf8) << 3;
515 base = yuv2rgb[uv + (yp[0] >> 2)];
516 COLORDITHER(lut, out, base, cd[z]);
517
518 base = yuv2rgb[uv + (yp[1] >> 2)];
519 COLORDITHER(lut, c, base, cd[z+1]);
520 out = (out >> 8) + c;
521
522 uv = ((up[1] - 128) & 0xf8) << 8;
523 uv |= ((vp[1] - 128) & 0xf8) << 3;
524 base = yuv2rgb[uv + (yp[2] >> 2)];
525 COLORDITHER(lut, c, base, cd[z+2]);
526 out = (out >> 8) + c;
527
528 base = yuv2rgb[uv + (yp[3] >> 2)];
529 COLORDITHER(lut, c, base, cd[z+3]);
530 xip[0] = (out >> 8) + c;
531
532 uv = ((up[2] - 128) & 0xf8) << 8;
533 uv |= ((vp[2] - 128) & 0xf8) << 3;
534 base = yuv2rgb[uv + (yp[4] >> 2)];
535 COLORDITHER(lut, out, base, cd[z]);
536
537 base = yuv2rgb[uv + (yp[5] >> 2)];
538 COLORDITHER(lut, c, base, cd[z+1]);
539 out = (out >> 8) + c;
540
541 uv = ((up[3] - 128) & 0xf8) << 8;
542 uv |= ((vp[3] - 128) & 0xf8) << 3;
543 base = yuv2rgb[uv + (yp[6] >> 2)];
544 COLORDITHER(lut, c, base, cd[z+2]);
545 out = (out >> 8) + c;
546
547 base = yuv2rgb[uv + (yp[7] >> 2)];
548 COLORDITHER(lut, c, base, cd[z+3]);
549 xip[1] = (out >> 8) + c;
550
551 yp += 8;
552 up += 4;
553 vp += 4;
554 xip += 2;
555
556 w -= 8;
557 if (w <= 0) {
558 w = width;
559 z = (z + 4) % 16;
560 }
561 }
562 }
563
564 void
565 putcolorimage(u_char *yp, u_char *up, u_char *vp, int scalebits)
566 {
567 const int len = image->width * image->height;/*FIXME*/
568
569 XSync(dpy, 0);
570 if (scalebits != 0)
571 rf_dither_scale((u_long *)image->data, yp, up, vp, scalebits);
572 else
573 rf_dither((u_long *)image->data, yp, up, vp, len);
574 #ifdef HAVE_SHM
575 if (!noshm)
576 XShmPutImage(dpy, wi.win, wi.gc, image,
577 0, 0, 0, 0,
578 ximage_width, ximage_height, 0);
579 else
580 #endif
581 XPutImage(dpy, wi.win, wi.gc, image,
582 0, 0, 0, 0,
583 ximage_width, ximage_height);
584 XFlush(dpy);
585 }
586
587
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.