|
|
1.1 root 1: // Emacs style mode select -*- C++ -*-
2: //-----------------------------------------------------------------------------
3: //
4: // $Id:$
5: //
6: // Copyright (C) 1993-1996 by id Software, Inc.
7: //
8: // This source is available for distribution and/or modification
9: // only under the terms of the DOOM Source Code License as
10: // published by id Software. All rights reserved.
11: //
12: // The source is distributed in the hope that it will be useful,
13: // but WITHOUT ANY WARRANTY; without even the implied warranty of
14: // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
15: // for more details.
16: //
17: // $Log:$
18: //
19: // DESCRIPTION:
20: // DOOM graphics stuff for X11, UNIX.
21: //
22: //-----------------------------------------------------------------------------
23:
24: static const char
25: rcsid[] = "$Id: i_x.c,v 1.6 1997/02/03 22:45:10 b1 Exp $";
26:
27: #include <stdlib.h>
28: #include <unistd.h>
29: #include <sys/ipc.h>
30: #include <sys/shm.h>
31:
32: #include <X11/Xlib.h>
33: #include <X11/Xutil.h>
34: #include <X11/keysym.h>
35:
36: #include <X11/extensions/XShm.h>
37: // Had to dig up XShm.c for this one.
38: // It is in the libXext, but not in the XFree86 headers.
39: #ifdef LINUX
40: int XShmGetEventBase( Display* dpy ); // problems with g++?
41: #endif
42:
43: #include <stdarg.h>
44: #include <sys/time.h>
45: #include <sys/types.h>
46: #include <sys/socket.h>
47:
48: #include <netinet/in.h>
49: #include <errnos.h>
50: #include <signal.h>
51:
52: #include "doomstat.h"
53: #include "i_system.h"
54: #include "v_video.h"
55: #include "m_argv.h"
56: #include "d_main.h"
57:
58: #include "doomdef.h"
59:
60: #define POINTER_WARP_COUNTDOWN 1
61:
62: Display* X_display=0;
63: Window X_mainWindow;
64: Colormap X_cmap;
65: Visual* X_visual;
66: GC X_gc;
67: XEvent X_event;
68: int X_screen;
69: XVisualInfo X_visualinfo;
70: XImage* image;
71: int X_width;
72: int X_height;
73:
74: // MIT SHared Memory extension.
75: boolean doShm;
76:
77: XShmSegmentInfo X_shminfo;
78: int X_shmeventtype;
79:
80: // Fake mouse handling.
81: // This cannot work properly w/o DGA.
82: // Needs an invisible mouse cursor at least.
83: boolean grabMouse;
84: int doPointerWarp = POINTER_WARP_COUNTDOWN;
85:
86: // Blocky mode,
87: // replace each 320x200 pixel with multiply*multiply pixels.
88: // According to Dave Taylor, it still is a bonehead thing
89: // to use ....
90: static int multiply=1;
91:
92:
93: //
94: // Translates the key currently in X_event
95: //
96:
97: int xlatekey(void)
98: {
99:
100: int rc;
101:
102: switch(rc = XKeycodeToKeysym(X_display, X_event.xkey.keycode, 0))
103: {
104: case XK_Left: rc = KEY_LEFTARROW; break;
105: case XK_Right: rc = KEY_RIGHTARROW; break;
106: case XK_Down: rc = KEY_DOWNARROW; break;
107: case XK_Up: rc = KEY_UPARROW; break;
108: case XK_Escape: rc = KEY_ESCAPE; break;
109: case XK_Return: rc = KEY_ENTER; break;
110: case XK_Tab: rc = KEY_TAB; break;
111: case XK_F1: rc = KEY_F1; break;
112: case XK_F2: rc = KEY_F2; break;
113: case XK_F3: rc = KEY_F3; break;
114: case XK_F4: rc = KEY_F4; break;
115: case XK_F5: rc = KEY_F5; break;
116: case XK_F6: rc = KEY_F6; break;
117: case XK_F7: rc = KEY_F7; break;
118: case XK_F8: rc = KEY_F8; break;
119: case XK_F9: rc = KEY_F9; break;
120: case XK_F10: rc = KEY_F10; break;
121: case XK_F11: rc = KEY_F11; break;
122: case XK_F12: rc = KEY_F12; break;
123:
124: case XK_BackSpace:
125: case XK_Delete: rc = KEY_BACKSPACE; break;
126:
127: case XK_Pause: rc = KEY_PAUSE; break;
128:
129: case XK_KP_Equal:
130: case XK_equal: rc = KEY_EQUALS; break;
131:
132: case XK_KP_Subtract:
133: case XK_minus: rc = KEY_MINUS; break;
134:
135: case XK_Shift_L:
136: case XK_Shift_R:
137: rc = KEY_RSHIFT;
138: break;
139:
140: case XK_Control_L:
141: case XK_Control_R:
142: rc = KEY_RCTRL;
143: break;
144:
145: case XK_Alt_L:
146: case XK_Meta_L:
147: case XK_Alt_R:
148: case XK_Meta_R:
149: rc = KEY_RALT;
150: break;
151:
152: default:
153: if (rc >= XK_space && rc <= XK_asciitilde)
154: rc = rc - XK_space + ' ';
155: if (rc >= 'A' && rc <= 'Z')
156: rc = rc - 'A' + 'a';
157: break;
158: }
159:
160: return rc;
161:
162: }
163:
164: void I_ShutdownGraphics(void)
165: {
166: // Detach from X server
167: if (!XShmDetach(X_display, &X_shminfo))
168: I_Error("XShmDetach() failed in I_ShutdownGraphics()");
169:
170: // Release shared memory.
171: shmdt(X_shminfo.shmaddr);
172: shmctl(X_shminfo.shmid, IPC_RMID, 0);
173:
174: // Paranoia.
175: image->data = NULL;
176: }
177:
178:
179:
180: //
181: // I_StartFrame
182: //
183: void I_StartFrame (void)
184: {
185: // er?
186:
187: }
188:
189: static int lastmousex = 0;
190: static int lastmousey = 0;
191: boolean mousemoved = false;
192: boolean shmFinished;
193:
194: void I_GetEvent(void)
195: {
196:
197: event_t event;
198:
199: // put event-grabbing stuff in here
200: XNextEvent(X_display, &X_event);
201: switch (X_event.type)
202: {
203: case KeyPress:
204: event.type = ev_keydown;
205: event.data1 = xlatekey();
206: D_PostEvent(&event);
207: // fprintf(stderr, "k");
208: break;
209: case KeyRelease:
210: event.type = ev_keyup;
211: event.data1 = xlatekey();
212: D_PostEvent(&event);
213: // fprintf(stderr, "ku");
214: break;
215: case ButtonPress:
216: event.type = ev_mouse;
217: event.data1 =
218: (X_event.xbutton.state & Button1Mask)
219: | (X_event.xbutton.state & Button2Mask ? 2 : 0)
220: | (X_event.xbutton.state & Button3Mask ? 4 : 0)
221: | (X_event.xbutton.button == Button1)
222: | (X_event.xbutton.button == Button2 ? 2 : 0)
223: | (X_event.xbutton.button == Button3 ? 4 : 0);
224: event.data2 = event.data3 = 0;
225: D_PostEvent(&event);
226: // fprintf(stderr, "b");
227: break;
228: case ButtonRelease:
229: event.type = ev_mouse;
230: event.data1 =
231: (X_event.xbutton.state & Button1Mask)
232: | (X_event.xbutton.state & Button2Mask ? 2 : 0)
233: | (X_event.xbutton.state & Button3Mask ? 4 : 0);
234: // suggest parentheses around arithmetic in operand of |
235: event.data1 =
236: event.data1
237: ^ (X_event.xbutton.button == Button1 ? 1 : 0)
238: ^ (X_event.xbutton.button == Button2 ? 2 : 0)
239: ^ (X_event.xbutton.button == Button3 ? 4 : 0);
240: event.data2 = event.data3 = 0;
241: D_PostEvent(&event);
242: // fprintf(stderr, "bu");
243: break;
244: case MotionNotify:
245: event.type = ev_mouse;
246: event.data1 =
247: (X_event.xmotion.state & Button1Mask)
248: | (X_event.xmotion.state & Button2Mask ? 2 : 0)
249: | (X_event.xmotion.state & Button3Mask ? 4 : 0);
250: event.data2 = (X_event.xmotion.x - lastmousex) << 2;
251: event.data3 = (lastmousey - X_event.xmotion.y) << 2;
252:
253: if (event.data2 || event.data3)
254: {
255: lastmousex = X_event.xmotion.x;
256: lastmousey = X_event.xmotion.y;
257: if (X_event.xmotion.x != X_width/2 &&
258: X_event.xmotion.y != X_height/2)
259: {
260: D_PostEvent(&event);
261: // fprintf(stderr, "m");
262: mousemoved = false;
263: } else
264: {
265: mousemoved = true;
266: }
267: }
268: break;
269:
270: case Expose:
271: case ConfigureNotify:
272: break;
273:
274: default:
275: if (doShm && X_event.type == X_shmeventtype) shmFinished = true;
276: break;
277: }
278:
279: }
280:
281: Cursor
282: createnullcursor
283: ( Display* display,
284: Window root )
285: {
286: Pixmap cursormask;
287: XGCValues xgc;
288: GC gc;
289: XColor dummycolour;
290: Cursor cursor;
291:
292: cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/);
293: xgc.function = GXclear;
294: gc = XCreateGC(display, cursormask, GCFunction, &xgc);
295: XFillRectangle(display, cursormask, gc, 0, 0, 1, 1);
296: dummycolour.pixel = 0;
297: dummycolour.red = 0;
298: dummycolour.flags = 04;
299: cursor = XCreatePixmapCursor(display, cursormask, cursormask,
300: &dummycolour,&dummycolour, 0,0);
301: XFreePixmap(display,cursormask);
302: XFreeGC(display,gc);
303: return cursor;
304: }
305:
306: //
307: // I_StartTic
308: //
309: void I_StartTic (void)
310: {
311:
312: if (!X_display)
313: return;
314:
315: while (XPending(X_display))
316: I_GetEvent();
317:
318: // Warp the pointer back to the middle of the window
319: // or it will wander off - that is, the game will
320: // loose input focus within X11.
321: if (grabMouse)
322: {
323: if (!--doPointerWarp)
324: {
325: XWarpPointer( X_display,
326: None,
327: X_mainWindow,
328: 0, 0,
329: 0, 0,
330: X_width/2, X_height/2);
331:
332: doPointerWarp = POINTER_WARP_COUNTDOWN;
333: }
334: }
335:
336: mousemoved = false;
337:
338: }
339:
340:
341: //
342: // I_UpdateNoBlit
343: //
344: void I_UpdateNoBlit (void)
345: {
346: // what is this?
347: }
348:
349: //
350: // I_FinishUpdate
351: //
352: void I_FinishUpdate (void)
353: {
354:
355: static int lasttic;
356: int tics;
357: int i;
358: // UNUSED static unsigned char *bigscreen=0;
359:
360: // draws little dots on the bottom of the screen
361: if (devparm)
362: {
363:
364: i = I_GetTime();
365: tics = i - lasttic;
366: lasttic = i;
367: if (tics > 20) tics = 20;
368:
369: for (i=0 ; i<tics*2 ; i+=2)
370: screens[0][ (SCREENHEIGHT-1)*SCREENWIDTH + i] = 0xff;
371: for ( ; i<20*2 ; i+=2)
372: screens[0][ (SCREENHEIGHT-1)*SCREENWIDTH + i] = 0x0;
373:
374: }
375:
376: // scales the screen size before blitting it
377: if (multiply == 2)
378: {
379: unsigned int *olineptrs[2];
380: unsigned int *ilineptr;
381: int x, y, i;
382: unsigned int twoopixels;
383: unsigned int twomoreopixels;
384: unsigned int fouripixels;
385:
386: ilineptr = (unsigned int *) (screens[0]);
387: for (i=0 ; i<2 ; i++)
388: olineptrs[i] = (unsigned int *) &image->data[i*X_width];
389:
390: y = SCREENHEIGHT;
391: while (y--)
392: {
393: x = SCREENWIDTH;
394: do
395: {
396: fouripixels = *ilineptr++;
397: twoopixels = (fouripixels & 0xff000000)
398: | ((fouripixels>>8) & 0xffff00)
399: | ((fouripixels>>16) & 0xff);
400: twomoreopixels = ((fouripixels<<16) & 0xff000000)
401: | ((fouripixels<<8) & 0xffff00)
402: | (fouripixels & 0xff);
403: #ifdef __BIG_ENDIAN__
404: *olineptrs[0]++ = twoopixels;
405: *olineptrs[1]++ = twoopixels;
406: *olineptrs[0]++ = twomoreopixels;
407: *olineptrs[1]++ = twomoreopixels;
408: #else
409: *olineptrs[0]++ = twomoreopixels;
410: *olineptrs[1]++ = twomoreopixels;
411: *olineptrs[0]++ = twoopixels;
412: *olineptrs[1]++ = twoopixels;
413: #endif
414: } while (x-=4);
415: olineptrs[0] += X_width/4;
416: olineptrs[1] += X_width/4;
417: }
418:
419: }
420: else if (multiply == 3)
421: {
422: unsigned int *olineptrs[3];
423: unsigned int *ilineptr;
424: int x, y, i;
425: unsigned int fouropixels[3];
426: unsigned int fouripixels;
427:
428: ilineptr = (unsigned int *) (screens[0]);
429: for (i=0 ; i<3 ; i++)
430: olineptrs[i] = (unsigned int *) &image->data[i*X_width];
431:
432: y = SCREENHEIGHT;
433: while (y--)
434: {
435: x = SCREENWIDTH;
436: do
437: {
438: fouripixels = *ilineptr++;
439: fouropixels[0] = (fouripixels & 0xff000000)
440: | ((fouripixels>>8) & 0xff0000)
441: | ((fouripixels>>16) & 0xffff);
442: fouropixels[1] = ((fouripixels<<8) & 0xff000000)
443: | (fouripixels & 0xffff00)
444: | ((fouripixels>>8) & 0xff);
445: fouropixels[2] = ((fouripixels<<16) & 0xffff0000)
446: | ((fouripixels<<8) & 0xff00)
447: | (fouripixels & 0xff);
448: #ifdef __BIG_ENDIAN__
449: *olineptrs[0]++ = fouropixels[0];
450: *olineptrs[1]++ = fouropixels[0];
451: *olineptrs[2]++ = fouropixels[0];
452: *olineptrs[0]++ = fouropixels[1];
453: *olineptrs[1]++ = fouropixels[1];
454: *olineptrs[2]++ = fouropixels[1];
455: *olineptrs[0]++ = fouropixels[2];
456: *olineptrs[1]++ = fouropixels[2];
457: *olineptrs[2]++ = fouropixels[2];
458: #else
459: *olineptrs[0]++ = fouropixels[2];
460: *olineptrs[1]++ = fouropixels[2];
461: *olineptrs[2]++ = fouropixels[2];
462: *olineptrs[0]++ = fouropixels[1];
463: *olineptrs[1]++ = fouropixels[1];
464: *olineptrs[2]++ = fouropixels[1];
465: *olineptrs[0]++ = fouropixels[0];
466: *olineptrs[1]++ = fouropixels[0];
467: *olineptrs[2]++ = fouropixels[0];
468: #endif
469: } while (x-=4);
470: olineptrs[0] += 2*X_width/4;
471: olineptrs[1] += 2*X_width/4;
472: olineptrs[2] += 2*X_width/4;
473: }
474:
475: }
476: else if (multiply == 4)
477: {
478: // Broken. Gotta fix this some day.
479: void Expand4(unsigned *, double *);
480: Expand4 ((unsigned *)(screens[0]), (double *) (image->data));
481: }
482:
483: if (doShm)
484: {
485:
486: if (!XShmPutImage( X_display,
487: X_mainWindow,
488: X_gc,
489: image,
490: 0, 0,
491: 0, 0,
492: X_width, X_height,
493: True ))
494: I_Error("XShmPutImage() failed\n");
495:
496: // wait for it to finish and processes all input events
497: shmFinished = false;
498: do
499: {
500: I_GetEvent();
501: } while (!shmFinished);
502:
503: }
504: else
505: {
506:
507: // draw the image
508: XPutImage( X_display,
509: X_mainWindow,
510: X_gc,
511: image,
512: 0, 0,
513: 0, 0,
514: X_width, X_height );
515:
516: // sync up with server
517: XSync(X_display, False);
518:
519: }
520:
521: }
522:
523:
524: //
525: // I_ReadScreen
526: //
527: void I_ReadScreen (byte* scr)
528: {
529: memcpy (scr, screens[0], SCREENWIDTH*SCREENHEIGHT);
530: }
531:
532:
533: //
534: // Palette stuff.
535: //
536: static XColor colors[256];
537:
538: void UploadNewPalette(Colormap cmap, byte *palette)
539: {
540:
541: register int i;
542: register int c;
543: static boolean firstcall = true;
544:
545: #ifdef __cplusplus
546: if (X_visualinfo.c_class == PseudoColor && X_visualinfo.depth == 8)
547: #else
548: if (X_visualinfo.class == PseudoColor && X_visualinfo.depth == 8)
549: #endif
550: {
551: // initialize the colormap
552: if (firstcall)
553: {
554: firstcall = false;
555: for (i=0 ; i<256 ; i++)
556: {
557: colors[i].pixel = i;
558: colors[i].flags = DoRed|DoGreen|DoBlue;
559: }
560: }
561:
562: // set the X colormap entries
563: for (i=0 ; i<256 ; i++)
564: {
565: c = gammatable[usegamma][*palette++];
566: colors[i].red = (c<<8) + c;
567: c = gammatable[usegamma][*palette++];
568: colors[i].green = (c<<8) + c;
569: c = gammatable[usegamma][*palette++];
570: colors[i].blue = (c<<8) + c;
571: }
572:
573: // store the colors to the current colormap
574: XStoreColors(X_display, cmap, colors, 256);
575:
576: }
577: }
578:
579: //
580: // I_SetPalette
581: //
582: void I_SetPalette (byte* palette)
583: {
584: UploadNewPalette(X_cmap, palette);
585: }
586:
587:
588: //
589: // This function is probably redundant,
590: // if XShmDetach works properly.
591: // ddt never detached the XShm memory,
592: // thus there might have been stale
593: // handles accumulating.
594: //
595: void grabsharedmemory(int size)
596: {
597:
598: int key = ('d'<<24) | ('o'<<16) | ('o'<<8) | 'm';
599: struct shmid_ds shminfo;
600: int minsize = 320*200;
601: int id;
602: int rc;
603: // UNUSED int done=0;
604: int pollution=5;
605:
606: // try to use what was here before
607: do
608: {
609: id = shmget((key_t) key, minsize, 0777); // just get the id
610: if (id != -1)
611: {
612: rc=shmctl(id, IPC_STAT, &shminfo); // get stats on it
613: if (!rc)
614: {
615: if (shminfo.shm_nattch)
616: {
617: fprintf(stderr, "User %d appears to be running "
618: "DOOM. Is that wise?\n", shminfo.shm_cpid);
619: key++;
620: }
621: else
622: {
623: if (getuid() == shminfo.shm_perm.cuid)
624: {
625: rc = shmctl(id, IPC_RMID, 0);
626: if (!rc)
627: fprintf(stderr,
628: "Was able to kill my old shared memory\n");
629: else
630: I_Error("Was NOT able to kill my old shared memory");
631:
632: id = shmget((key_t)key, size, IPC_CREAT|0777);
633: if (id==-1)
634: I_Error("Could not get shared memory");
635:
636: rc=shmctl(id, IPC_STAT, &shminfo);
637:
638: break;
639:
640: }
641: if (size >= shminfo.shm_segsz)
642: {
643: fprintf(stderr,
644: "will use %d's stale shared memory\n",
645: shminfo.shm_cpid);
646: break;
647: }
648: else
649: {
650: fprintf(stderr,
651: "warning: can't use stale "
652: "shared memory belonging to id %d, "
653: "key=0x%x\n",
654: shminfo.shm_cpid, key);
655: key++;
656: }
657: }
658: }
659: else
660: {
661: I_Error("could not get stats on key=%d", key);
662: }
663: }
664: else
665: {
666: id = shmget((key_t)key, size, IPC_CREAT|0777);
667: if (id==-1)
668: {
669: extern int errno;
670: fprintf(stderr, "errno=%d\n", errno);
671: I_Error("Could not get any shared memory");
672: }
673: break;
674: }
675: } while (--pollution);
676:
677: if (!pollution)
678: {
679: I_Error("Sorry, system too polluted with stale "
680: "shared memory segments.\n");
681: }
682:
683: X_shminfo.shmid = id;
684:
685: // attach to the shared memory segment
686: image->data = X_shminfo.shmaddr = shmat(id, 0, 0);
687:
688: fprintf(stderr, "shared memory id=%d, addr=0x%x\n", id,
689: (int) (image->data));
690: }
691:
692: void I_InitGraphics(void)
693: {
694:
695: char* displayname;
696: char* d;
697: int n;
698: int pnum;
699: int x=0;
700: int y=0;
701:
702: // warning: char format, different type arg
703: char xsign=' ';
704: char ysign=' ';
705:
706: int oktodraw;
707: unsigned long attribmask;
708: XSetWindowAttributes attribs;
709: XGCValues xgcvalues;
710: int valuemask;
711: static int firsttime=1;
712:
713: if (!firsttime)
714: return;
715: firsttime = 0;
716:
717: signal(SIGINT, (void (*)(int)) I_Quit);
718:
719: if (M_CheckParm("-2"))
720: multiply = 2;
721:
722: if (M_CheckParm("-3"))
723: multiply = 3;
724:
725: if (M_CheckParm("-4"))
726: multiply = 4;
727:
728: X_width = SCREENWIDTH * multiply;
729: X_height = SCREENHEIGHT * multiply;
730:
731: // check for command-line display name
732: if ( (pnum=M_CheckParm("-disp")) ) // suggest parentheses around assignment
733: displayname = myargv[pnum+1];
734: else
735: displayname = 0;
736:
737: // check if the user wants to grab the mouse (quite unnice)
738: grabMouse = !!M_CheckParm("-grabmouse");
739:
740: // check for command-line geometry
741: if ( (pnum=M_CheckParm("-geom")) ) // suggest parentheses around assignment
742: {
743: // warning: char format, different type arg 3,5
744: n = sscanf(myargv[pnum+1], "%c%d%c%d", &xsign, &x, &ysign, &y);
745:
746: if (n==2)
747: x = y = 0;
748: else if (n==6)
749: {
750: if (xsign == '-')
751: x = -x;
752: if (ysign == '-')
753: y = -y;
754: }
755: else
756: I_Error("bad -geom parameter");
757: }
758:
759: // open the display
760: X_display = XOpenDisplay(displayname);
761: if (!X_display)
762: {
763: if (displayname)
764: I_Error("Could not open display [%s]", displayname);
765: else
766: I_Error("Could not open display (DISPLAY=[%s])", getenv("DISPLAY"));
767: }
768:
769: // use the default visual
770: X_screen = DefaultScreen(X_display);
771: if (!XMatchVisualInfo(X_display, X_screen, 8, PseudoColor, &X_visualinfo))
772: I_Error("xdoom currently only supports 256-color PseudoColor screens");
773: X_visual = X_visualinfo.visual;
774:
775: // check for the MITSHM extension
776: doShm = XShmQueryExtension(X_display);
777:
778: // even if it's available, make sure it's a local connection
779: if (doShm)
780: {
781: if (!displayname) displayname = (char *) getenv("DISPLAY");
782: if (displayname)
783: {
784: d = displayname;
785: while (*d && (*d != ':')) d++;
786: if (*d) *d = 0;
787: if (!(!strcasecmp(displayname, "unix") || !*displayname)) doShm = false;
788: }
789: }
790:
791: fprintf(stderr, "Using MITSHM extension\n");
792:
793: // create the colormap
794: X_cmap = XCreateColormap(X_display, RootWindow(X_display,
795: X_screen), X_visual, AllocAll);
796:
797: // setup attributes for main window
798: attribmask = CWEventMask | CWColormap | CWBorderPixel;
799: attribs.event_mask =
800: KeyPressMask
801: | KeyReleaseMask
802: // | PointerMotionMask | ButtonPressMask | ButtonReleaseMask
803: | ExposureMask;
804:
805: attribs.colormap = X_cmap;
806: attribs.border_pixel = 0;
807:
808: // create the main window
809: X_mainWindow = XCreateWindow( X_display,
810: RootWindow(X_display, X_screen),
811: x, y,
812: X_width, X_height,
813: 0, // borderwidth
814: 8, // depth
815: InputOutput,
816: X_visual,
817: attribmask,
818: &attribs );
819:
820: XDefineCursor(X_display, X_mainWindow,
821: createnullcursor( X_display, X_mainWindow ) );
822:
823: // create the GC
824: valuemask = GCGraphicsExposures;
825: xgcvalues.graphics_exposures = False;
826: X_gc = XCreateGC( X_display,
827: X_mainWindow,
828: valuemask,
829: &xgcvalues );
830:
831: // map the window
832: XMapWindow(X_display, X_mainWindow);
833:
834: // wait until it is OK to draw
835: oktodraw = 0;
836: while (!oktodraw)
837: {
838: XNextEvent(X_display, &X_event);
839: if (X_event.type == Expose
840: && !X_event.xexpose.count)
841: {
842: oktodraw = 1;
843: }
844: }
845:
846: // grabs the pointer so it is restricted to this window
847: if (grabMouse)
848: XGrabPointer(X_display, X_mainWindow, True,
849: ButtonPressMask|ButtonReleaseMask|PointerMotionMask,
850: GrabModeAsync, GrabModeAsync,
851: X_mainWindow, None, CurrentTime);
852:
853: if (doShm)
854: {
855:
856: X_shmeventtype = XShmGetEventBase(X_display) + ShmCompletion;
857:
858: // create the image
859: image = XShmCreateImage( X_display,
860: X_visual,
861: 8,
862: ZPixmap,
863: 0,
864: &X_shminfo,
865: X_width,
866: X_height );
867:
868: grabsharedmemory(image->bytes_per_line * image->height);
869:
870:
871: // UNUSED
872: // create the shared memory segment
873: // X_shminfo.shmid = shmget (IPC_PRIVATE,
874: // image->bytes_per_line * image->height, IPC_CREAT | 0777);
875: // if (X_shminfo.shmid < 0)
876: // {
877: // perror("");
878: // I_Error("shmget() failed in InitGraphics()");
879: // }
880: // fprintf(stderr, "shared memory id=%d\n", X_shminfo.shmid);
881: // attach to the shared memory segment
882: // image->data = X_shminfo.shmaddr = shmat(X_shminfo.shmid, 0, 0);
883:
884:
885: if (!image->data)
886: {
887: perror("");
888: I_Error("shmat() failed in InitGraphics()");
889: }
890:
891: // get the X server to attach to it
892: if (!XShmAttach(X_display, &X_shminfo))
893: I_Error("XShmAttach() failed in InitGraphics()");
894:
895: }
896: else
897: {
898: image = XCreateImage( X_display,
899: X_visual,
900: 8,
901: ZPixmap,
902: 0,
903: (char*)malloc(X_width * X_height),
904: X_width, X_height,
905: 8,
906: X_width );
907:
908: }
909:
910: if (multiply == 1)
911: screens[0] = (unsigned char *) (image->data);
912: else
913: screens[0] = (unsigned char *) malloc (SCREENWIDTH * SCREENHEIGHT);
914:
915: }
916:
917:
918: unsigned exptable[256];
919:
920: void InitExpand (void)
921: {
922: int i;
923:
924: for (i=0 ; i<256 ; i++)
925: exptable[i] = i | (i<<8) | (i<<16) | (i<<24);
926: }
927:
928: double exptable2[256*256];
929:
930: void InitExpand2 (void)
931: {
932: int i;
933: int j;
934: // UNUSED unsigned iexp, jexp;
935: double* exp;
936: union
937: {
938: double d;
939: unsigned u[2];
940: } pixel;
941:
942: printf ("building exptable2...\n");
943: exp = exptable2;
944: for (i=0 ; i<256 ; i++)
945: {
946: pixel.u[0] = i | (i<<8) | (i<<16) | (i<<24);
947: for (j=0 ; j<256 ; j++)
948: {
949: pixel.u[1] = j | (j<<8) | (j<<16) | (j<<24);
950: *exp++ = pixel.d;
951: }
952: }
953: printf ("done.\n");
954: }
955:
956: int inited;
957:
958: void
959: Expand4
960: ( unsigned* lineptr,
961: double* xline )
962: {
963: double dpixel;
964: unsigned x;
965: unsigned y;
966: unsigned fourpixels;
967: unsigned step;
968: double* exp;
969:
970: exp = exptable2;
971: if (!inited)
972: {
973: inited = 1;
974: InitExpand2 ();
975: }
976:
977:
978: step = 3*SCREENWIDTH/2;
979:
980: y = SCREENHEIGHT-1;
981: do
982: {
983: x = SCREENWIDTH;
984:
985: do
986: {
987: fourpixels = lineptr[0];
988:
989: dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) );
990: xline[0] = dpixel;
991: xline[160] = dpixel;
992: xline[320] = dpixel;
993: xline[480] = dpixel;
994:
995: dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) );
996: xline[1] = dpixel;
997: xline[161] = dpixel;
998: xline[321] = dpixel;
999: xline[481] = dpixel;
1000:
1001: fourpixels = lineptr[1];
1002:
1003: dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) );
1004: xline[2] = dpixel;
1005: xline[162] = dpixel;
1006: xline[322] = dpixel;
1007: xline[482] = dpixel;
1008:
1009: dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) );
1010: xline[3] = dpixel;
1011: xline[163] = dpixel;
1012: xline[323] = dpixel;
1013: xline[483] = dpixel;
1014:
1015: fourpixels = lineptr[2];
1016:
1017: dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) );
1018: xline[4] = dpixel;
1019: xline[164] = dpixel;
1020: xline[324] = dpixel;
1021: xline[484] = dpixel;
1022:
1023: dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) );
1024: xline[5] = dpixel;
1025: xline[165] = dpixel;
1026: xline[325] = dpixel;
1027: xline[485] = dpixel;
1028:
1029: fourpixels = lineptr[3];
1030:
1031: dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) );
1032: xline[6] = dpixel;
1033: xline[166] = dpixel;
1034: xline[326] = dpixel;
1035: xline[486] = dpixel;
1036:
1037: dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) );
1038: xline[7] = dpixel;
1039: xline[167] = dpixel;
1040: xline[327] = dpixel;
1041: xline[487] = dpixel;
1042:
1043: lineptr+=4;
1044: xline+=8;
1045: } while (x-=16);
1046: xline += step;
1047: } while (y--);
1048: }
1049:
1050:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.