|
|
1.1 ! root 1: // vid_x.c -- general x video driver ! 2: ! 3: #define _BSD ! 4: ! 5: #include <ctype.h> ! 6: #include <sys/time.h> ! 7: #include <sys/types.h> ! 8: #include <unistd.h> ! 9: #include <signal.h> ! 10: #include <stdlib.h> ! 11: #include <stdio.h> ! 12: #include <string.h> ! 13: #include <sys/ipc.h> ! 14: #include <sys/shm.h> ! 15: #include <X11/Xlib.h> ! 16: #include <X11/Xutil.h> ! 17: #include <X11/Xatom.h> ! 18: #include <X11/keysym.h> ! 19: #include <X11/extensions/XShm.h> ! 20: ! 21: #include "quakedef.h" ! 22: #include "d_local.h" ! 23: ! 24: typedef struct ! 25: { ! 26: int input; ! 27: int output; ! 28: } keymap_t; ! 29: ! 30: viddef_t vid; // global video state ! 31: unsigned short d_8to16table[256]; ! 32: ! 33: int num_shades=32; ! 34: ! 35: int d_con_indirect = 0; ! 36: ! 37: int vid_buffersize; ! 38: ! 39: static qboolean doShm; ! 40: static Display *x_disp; ! 41: static Colormap x_cmap; ! 42: static Window x_win; ! 43: static GC x_gc; ! 44: static Visual *x_vis; ! 45: static XVisualInfo *x_visinfo; ! 46: //static XImage *x_image; ! 47: ! 48: static int x_shmeventtype; ! 49: //static XShmSegmentInfo x_shminfo; ! 50: ! 51: static qboolean oktodraw = false; ! 52: ! 53: int XShmQueryExtension(Display *); ! 54: int XShmGetEventBase(Display *); ! 55: ! 56: int current_framebuffer; ! 57: static XImage *x_framebuffer[2] = { 0, 0 }; ! 58: static XShmSegmentInfo x_shminfo[2]; ! 59: ! 60: static int verbose=0; ! 61: ! 62: static byte current_palette[768]; ! 63: ! 64: static long X11_highhunkmark; ! 65: static long X11_buffersize; ! 66: ! 67: int vid_surfcachesize; ! 68: void *vid_surfcache; ! 69: ! 70: void (*vid_menudrawfn)(void); ! 71: void (*vid_menukeyfn)(int key); ! 72: void VID_MenuKey (int key); ! 73: ! 74: // ======================================================================== ! 75: // Tragic death handler ! 76: // ======================================================================== ! 77: ! 78: void TragicDeath(int signal_num) ! 79: { ! 80: XAutoRepeatOn(x_disp); ! 81: XCloseDisplay(x_disp); ! 82: Sys_Error("This death brought to you by the number %d\n", signal_num); ! 83: } ! 84: ! 85: // ======================================================================== ! 86: // makes a null cursor ! 87: // ======================================================================== ! 88: ! 89: static Cursor CreateNullCursor(Display *display, Window root) ! 90: { ! 91: Pixmap cursormask; ! 92: XGCValues xgc; ! 93: GC gc; ! 94: XColor dummycolour; ! 95: Cursor cursor; ! 96: ! 97: cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/); ! 98: xgc.function = GXclear; ! 99: gc = XCreateGC(display, cursormask, GCFunction, &xgc); ! 100: XFillRectangle(display, cursormask, gc, 0, 0, 1, 1); ! 101: dummycolour.pixel = 0; ! 102: dummycolour.red = 0; ! 103: dummycolour.flags = 04; ! 104: cursor = XCreatePixmapCursor(display, cursormask, cursormask, ! 105: &dummycolour,&dummycolour, 0,0); ! 106: XFreePixmap(display,cursormask); ! 107: XFreeGC(display,gc); ! 108: return cursor; ! 109: } ! 110: ! 111: void ResetFrameBuffer(void) ! 112: { ! 113: ! 114: int mem; ! 115: int pwidth; ! 116: ! 117: if (x_framebuffer[0]) ! 118: { ! 119: free(x_framebuffer[0]->data); ! 120: free(x_framebuffer[0]); ! 121: } ! 122: ! 123: if (d_pzbuffer) ! 124: { ! 125: D_FlushCaches (); ! 126: Hunk_FreeToHighMark (X11_highhunkmark); ! 127: d_pzbuffer = NULL; ! 128: } ! 129: X11_highhunkmark = Hunk_HighMark (); ! 130: ! 131: // alloc an extra line in case we want to wrap, and allocate the z-buffer ! 132: X11_buffersize = vid.width * vid.height * sizeof (*d_pzbuffer); ! 133: ! 134: vid_surfcachesize = D_SurfaceCacheForRes (vid.width, vid.height); ! 135: ! 136: X11_buffersize += vid_surfcachesize; ! 137: ! 138: d_pzbuffer = Hunk_HighAllocName (X11_buffersize, "video"); ! 139: if (d_pzbuffer == NULL) ! 140: Sys_Error ("Not enough memory for video mode\n"); ! 141: ! 142: vid_surfcache = (byte *) d_pzbuffer ! 143: + vid.width * vid.height * sizeof (*d_pzbuffer); ! 144: ! 145: D_InitCaches(vid_surfcache, vid_surfcachesize); ! 146: ! 147: pwidth = x_visinfo->depth / 8; ! 148: if (pwidth == 3) pwidth = 4; ! 149: mem = ((vid.width*pwidth+7)&~7) * vid.height; ! 150: ! 151: x_framebuffer[0] = XCreateImage( x_disp, ! 152: x_vis, ! 153: x_visinfo->depth, ! 154: ZPixmap, ! 155: 0, ! 156: malloc(mem), ! 157: vid.width, vid.height, ! 158: 32, ! 159: 0); ! 160: ! 161: if (!x_framebuffer[0]) ! 162: Sys_Error("VID: XCreateImage failed\n"); ! 163: ! 164: vid.buffer = (byte*) (x_framebuffer[0]); ! 165: vid.conbuffer = vid.buffer; ! 166: ! 167: } ! 168: ! 169: void ResetSharedFrameBuffers(void) ! 170: { ! 171: ! 172: int size; ! 173: int key; ! 174: int minsize = getpagesize(); ! 175: int frm; ! 176: ! 177: if (d_pzbuffer) ! 178: { ! 179: D_FlushCaches (); ! 180: Hunk_FreeToHighMark (X11_highhunkmark); ! 181: d_pzbuffer = NULL; ! 182: } ! 183: ! 184: X11_highhunkmark = Hunk_HighMark (); ! 185: ! 186: // alloc an extra line in case we want to wrap, and allocate the z-buffer ! 187: X11_buffersize = vid.width * vid.height * sizeof (*d_pzbuffer); ! 188: ! 189: vid_surfcachesize = D_SurfaceCacheForRes (vid.width, vid.height); ! 190: ! 191: X11_buffersize += vid_surfcachesize; ! 192: ! 193: d_pzbuffer = Hunk_HighAllocName (X11_buffersize, "video"); ! 194: if (d_pzbuffer == NULL) ! 195: Sys_Error ("Not enough memory for video mode\n"); ! 196: ! 197: vid_surfcache = (byte *) d_pzbuffer ! 198: + vid.width * vid.height * sizeof (*d_pzbuffer); ! 199: ! 200: D_InitCaches(vid_surfcache, vid_surfcachesize); ! 201: ! 202: for (frm=0 ; frm<2 ; frm++) ! 203: { ! 204: ! 205: // free up old frame buffer memory ! 206: ! 207: if (x_framebuffer[frm]) ! 208: { ! 209: XShmDetach(x_disp, &x_shminfo[frm]); ! 210: free(x_framebuffer[frm]); ! 211: shmdt(x_shminfo[frm].shmaddr); ! 212: } ! 213: ! 214: // create the image ! 215: ! 216: x_framebuffer[frm] = XShmCreateImage( x_disp, ! 217: x_vis, ! 218: x_visinfo->depth, ! 219: ZPixmap, ! 220: 0, ! 221: &x_shminfo[frm], ! 222: vid.width, ! 223: vid.height ); ! 224: ! 225: // grab shared memory ! 226: ! 227: size = x_framebuffer[frm]->bytes_per_line ! 228: * x_framebuffer[frm]->height; ! 229: if (size < minsize) ! 230: Sys_Error("VID: Window must use at least %d bytes\n", minsize); ! 231: ! 232: key = random(); ! 233: x_shminfo[frm].shmid = shmget((key_t)key, size, IPC_CREAT|0777); ! 234: if (x_shminfo[frm].shmid==-1) ! 235: Sys_Error("VID: Could not get any shared memory\n"); ! 236: ! 237: // attach to the shared memory segment ! 238: x_shminfo[frm].shmaddr = ! 239: (void *) shmat(x_shminfo[frm].shmid, 0, 0); ! 240: ! 241: printf("VID: shared memory id=%d, addr=0x%lx\n", x_shminfo[frm].shmid, ! 242: (long) x_shminfo[frm].shmaddr); ! 243: ! 244: x_framebuffer[frm]->data = x_shminfo[frm].shmaddr; ! 245: ! 246: // get the X server to attach to it ! 247: ! 248: if (!XShmAttach(x_disp, &x_shminfo[frm])) ! 249: Sys_Error("VID: XShmAttach() failed\n"); ! 250: XSync(x_disp, 0); ! 251: shmctl(x_shminfo[frm].shmid, IPC_RMID, 0); ! 252: ! 253: } ! 254: ! 255: } ! 256: ! 257: // Called at startup to set up translation tables, takes 256 8 bit RGB values ! 258: // the palette data will go away after the call, so it must be copied off if ! 259: // the video driver will need it again ! 260: ! 261: void VID_Init (unsigned char *palette) ! 262: { ! 263: ! 264: int pnum, i; ! 265: XVisualInfo template; ! 266: int num_visuals; ! 267: int template_mask; ! 268: ! 269: vid.width = 320; ! 270: vid.height = 200; ! 271: vid.maxwarpwidth = WARP_WIDTH; ! 272: vid.maxwarpheight = WARP_HEIGHT; ! 273: vid.numpages = 2; ! 274: vid.colormap = host_colormap; ! 275: // vid.cbits = VID_CBITS; ! 276: // vid.grades = VID_GRADES; ! 277: vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048)); ! 278: ! 279: srandom(getpid()); ! 280: ! 281: verbose=COM_CheckParm("-verbose"); ! 282: ! 283: // open the display ! 284: x_disp = XOpenDisplay(0); ! 285: if (!x_disp) ! 286: { ! 287: if (getenv("DISPLAY")) ! 288: Sys_Error("VID: Could not open display [%s]\n", ! 289: getenv("DISPLAY")); ! 290: else ! 291: Sys_Error("VID: Could not open local display\n"); ! 292: } ! 293: ! 294: // catch signals so i can turn on auto-repeat ! 295: ! 296: { ! 297: struct sigaction sa; ! 298: sigaction(SIGINT, 0, &sa); ! 299: sa.sa_handler = TragicDeath; ! 300: sigaction(SIGINT, &sa, 0); ! 301: sigaction(SIGTERM, &sa, 0); ! 302: } ! 303: ! 304: XAutoRepeatOff(x_disp); ! 305: ! 306: // for debugging only ! 307: XSynchronize(x_disp, True); ! 308: ! 309: // check for command-line window size ! 310: if ((pnum=COM_CheckParm("-winsize"))) ! 311: { ! 312: if (pnum >= com_argc-2) ! 313: Sys_Error("VID: -winsize <width> <height>\n"); ! 314: vid.width = Q_atoi(com_argv[pnum+1]); ! 315: vid.height = Q_atoi(com_argv[pnum+2]); ! 316: if (!vid.width || !vid.height) ! 317: Sys_Error("VID: Bad window width/height\n"); ! 318: } ! 319: ! 320: template_mask = 0; ! 321: ! 322: // specify a visual id ! 323: if ((pnum=COM_CheckParm("-visualid"))) ! 324: { ! 325: if (pnum >= com_argc-1) ! 326: Sys_Error("VID: -visualid <id#>\n"); ! 327: template.visualid = Q_atoi(com_argv[pnum+1]); ! 328: template_mask = VisualIDMask; ! 329: } ! 330: ! 331: // If not specified, use default visual ! 332: else ! 333: { ! 334: int screen; ! 335: screen = XDefaultScreen(x_disp); ! 336: template.visualid = ! 337: XVisualIDFromVisual(XDefaultVisual(x_disp, screen)); ! 338: template_mask = VisualIDMask; ! 339: } ! 340: ! 341: // pick a visual- warn if more than one was available ! 342: x_visinfo = XGetVisualInfo(x_disp, template_mask, &template, &num_visuals); ! 343: if (num_visuals > 1) ! 344: { ! 345: printf("Found more than one visual id at depth %d:\n", template.depth); ! 346: for (i=0 ; i<num_visuals ; i++) ! 347: printf(" -visualid %d\n", (int)(x_visinfo[i].visualid)); ! 348: } ! 349: else if (num_visuals == 0) ! 350: { ! 351: if (template_mask == VisualIDMask) ! 352: Sys_Error("VID: Bad visual id %d\n", template.visualid); ! 353: else ! 354: Sys_Error("VID: No visuals at depth %d\n", template.depth); ! 355: } ! 356: ! 357: if (verbose) ! 358: { ! 359: printf("Using visualid %d:\n", (int)(x_visinfo->visualid)); ! 360: printf(" screen %d\n", x_visinfo->screen); ! 361: printf(" red_mask 0x%x\n", (int)(x_visinfo->red_mask)); ! 362: printf(" green_mask 0x%x\n", (int)(x_visinfo->green_mask)); ! 363: printf(" blue_mask 0x%x\n", (int)(x_visinfo->blue_mask)); ! 364: printf(" colormap_size %d\n", x_visinfo->colormap_size); ! 365: printf(" bits_per_rgb %d\n", x_visinfo->bits_per_rgb); ! 366: } ! 367: ! 368: x_vis = x_visinfo->visual; ! 369: ! 370: // setup attributes for main window ! 371: { ! 372: int attribmask = CWEventMask | CWColormap | CWBorderPixel; ! 373: XSetWindowAttributes attribs; ! 374: Colormap tmpcmap; ! 375: ! 376: tmpcmap = XCreateColormap(x_disp, XRootWindow(x_disp, ! 377: x_visinfo->screen), x_vis, AllocNone); ! 378: ! 379: attribs.event_mask = StructureNotifyMask | KeyPressMask ! 380: | KeyReleaseMask | ExposureMask; ! 381: attribs.border_pixel = 0; ! 382: attribs.colormap = tmpcmap; ! 383: ! 384: // create the main window ! 385: x_win = XCreateWindow( x_disp, ! 386: XRootWindow(x_disp, x_visinfo->screen), ! 387: 0, 0, // x, y ! 388: vid.width, vid.height, ! 389: 0, // borderwidth ! 390: x_visinfo->depth, ! 391: InputOutput, ! 392: x_vis, ! 393: attribmask, ! 394: &attribs ); ! 395: ! 396: if (x_visinfo->class != TrueColor) ! 397: XFreeColormap(x_disp, tmpcmap); ! 398: ! 399: } ! 400: ! 401: if (x_visinfo->depth == 8) ! 402: { ! 403: ! 404: // create and upload the palette ! 405: if (x_visinfo->class == PseudoColor) ! 406: { ! 407: x_cmap = XCreateColormap(x_disp, x_win, x_vis, AllocAll); ! 408: VID_SetPalette(palette); ! 409: XSetWindowColormap(x_disp, x_win, x_cmap); ! 410: } ! 411: ! 412: } ! 413: ! 414: // inviso cursor ! 415: XDefineCursor(x_disp, x_win, CreateNullCursor(x_disp, x_win)); ! 416: ! 417: // create the GC ! 418: { ! 419: XGCValues xgcvalues; ! 420: int valuemask = GCGraphicsExposures; ! 421: xgcvalues.graphics_exposures = False; ! 422: x_gc = XCreateGC(x_disp, x_win, valuemask, &xgcvalues ); ! 423: } ! 424: ! 425: // map the window ! 426: XMapWindow(x_disp, x_win); ! 427: ! 428: // wait for first exposure event ! 429: { ! 430: XEvent event; ! 431: do ! 432: { ! 433: XNextEvent(x_disp, &event); ! 434: if (event.type == Expose && !event.xexpose.count) ! 435: oktodraw = true; ! 436: } while (!oktodraw); ! 437: } ! 438: // now safe to draw ! 439: ! 440: // even if MITSHM is available, make sure it's a local connection ! 441: if (XShmQueryExtension(x_disp)) ! 442: { ! 443: char *displayname; ! 444: doShm = true; ! 445: displayname = (char *) getenv("DISPLAY"); ! 446: if (displayname) ! 447: { ! 448: char *d = displayname; ! 449: while (*d && (*d != ':')) d++; ! 450: if (*d) *d = 0; ! 451: if (!(!strcasecmp(displayname, "unix") || !*displayname)) ! 452: doShm = false; ! 453: } ! 454: } ! 455: ! 456: if (doShm) ! 457: { ! 458: x_shmeventtype = XShmGetEventBase(x_disp) + ShmCompletion; ! 459: ResetSharedFrameBuffers(); ! 460: } ! 461: else ! 462: ResetFrameBuffer(); ! 463: ! 464: current_framebuffer = 0; ! 465: vid.rowbytes = x_framebuffer[0]->bytes_per_line; ! 466: vid.buffer = x_framebuffer[0]->data; ! 467: vid.direct = 0; ! 468: vid.conbuffer = x_framebuffer[0]->data; ! 469: vid.conrowbytes = vid.rowbytes; ! 470: vid.conwidth = vid.width; ! 471: vid.conheight = vid.height; ! 472: vid.aspect = ((float)vid.height / (float)vid.width) * (320.0 / 240.0); ! 473: ! 474: // XSynchronize(x_disp, False); ! 475: ! 476: } ! 477: ! 478: void VID_ShiftPalette(unsigned char *p) ! 479: { ! 480: VID_SetPalette(p); ! 481: } ! 482: ! 483: void VID_SetPalette(unsigned char *palette) ! 484: { ! 485: ! 486: int i; ! 487: XColor colors[256]; ! 488: ! 489: if (x_visinfo->class == PseudoColor && x_visinfo->depth == 8) ! 490: { ! 491: if (palette != current_palette) ! 492: memcpy(current_palette, palette, 768); ! 493: for (i=0 ; i<256 ; i++) ! 494: { ! 495: colors[i].pixel = i; ! 496: colors[i].flags = DoRed|DoGreen|DoBlue; ! 497: colors[i].red = palette[i*3] * 257; ! 498: colors[i].green = palette[i*3+1] * 257; ! 499: colors[i].blue = palette[i*3+2] * 257; ! 500: } ! 501: XStoreColors(x_disp, x_cmap, colors, 256); ! 502: } ! 503: ! 504: } ! 505: ! 506: // Called at shutdown ! 507: ! 508: void VID_Shutdown (void) ! 509: { ! 510: Con_Printf("VID_Shutdown\n"); ! 511: XAutoRepeatOn(x_disp); ! 512: XCloseDisplay(x_disp); ! 513: } ! 514: ! 515: int XLateKey(XKeyEvent *ev) ! 516: { ! 517: ! 518: int key; ! 519: char buf[64]; ! 520: KeySym keysym; ! 521: ! 522: key = 0; ! 523: ! 524: XLookupString(ev, buf, sizeof buf, &keysym, 0); ! 525: ! 526: switch(keysym) ! 527: { ! 528: case XK_Page_Up: key = K_PGUP; break; ! 529: case XK_Page_Down: key = K_PGDN; break; ! 530: case XK_Home: key = K_HOME; break; ! 531: case XK_End: key = K_END; break; ! 532: case XK_Left: key = K_LEFTARROW; break; ! 533: case XK_Right: key = K_RIGHTARROW; break; ! 534: case XK_Down: key = K_DOWNARROW; break; ! 535: case XK_Up: key = K_UPARROW; break; ! 536: case XK_Escape: key = K_ESCAPE; break; ! 537: case XK_Return: key = K_ENTER; break; ! 538: case XK_Tab: key = K_TAB; break; ! 539: case XK_F1: key = K_F1; break; ! 540: case XK_F2: key = K_F2; break; ! 541: case XK_F3: key = K_F3; break; ! 542: case XK_F4: key = K_F4; break; ! 543: case XK_F5: key = K_F5; break; ! 544: case XK_F6: key = K_F6; break; ! 545: case XK_F7: key = K_F7; break; ! 546: case XK_F8: key = K_F8; break; ! 547: case XK_F9: key = K_F9; break; ! 548: case XK_F10: key = K_F10; break; ! 549: case XK_F11: key = K_F11; break; ! 550: case XK_F12: key = K_F12; break; ! 551: case XK_BackSpace: ! 552: case XK_Delete: key = K_BACKSPACE; break; ! 553: case XK_Pause: key = K_PAUSE; break; ! 554: case XK_Shift_L: ! 555: case XK_Shift_R: key = K_SHIFT; break; ! 556: case XK_Execute: ! 557: case XK_Control_L: ! 558: case XK_Control_R: key = K_CTRL; break; ! 559: case XK_Alt_L: ! 560: case XK_Meta_L: ! 561: case XK_Alt_R: ! 562: case XK_Meta_R: key = K_ALT; break; ! 563: ! 564: case 0x021: key = '1';break;/* [!] */ ! 565: case 0x040: key = '2';break;/* [@] */ ! 566: case 0x023: key = '3';break;/* [#] */ ! 567: case 0x024: key = '4';break;/* [$] */ ! 568: case 0x025: key = '5';break;/* [%] */ ! 569: case 0x05e: key = '6';break;/* [^] */ ! 570: case 0x026: key = '7';break;/* [&] */ ! 571: case 0x02a: key = '8';break;/* [*] */ ! 572: case 0x028: key = '9';;break;/* [(] */ ! 573: case 0x029: key = '0';break;/* [)] */ ! 574: case 0x05f: key = '-';break;/* [_] */ ! 575: case 0x02b: key = '=';break;/* [+] */ ! 576: case 0x07c: key = '\'';break;/* [|] */ ! 577: case 0x07d: key = '[';break;/* [}] */ ! 578: case 0x07b: key = ']';break;/* [{] */ ! 579: case 0x022: key = '\'';break;/* ["] */ ! 580: case 0x03a: key = ';';break;/* [:] */ ! 581: case 0x03f: key = '/';break;/* [?] */ ! 582: case 0x03e: key = '.';break;/* [>] */ ! 583: case 0x03c: key = ',';break;/* [<] */ ! 584: ! 585: default: ! 586: key = *(unsigned char*)buf; ! 587: if (key >= 'A' && key <= 'Z') ! 588: key = key - 'A' + 'a'; ! 589: // fprintf(stderr, "case 0x0%x: key = ___;break;/* [%c] */\n", keysym); ! 590: break; ! 591: } ! 592: ! 593: return key; ! 594: ! 595: } ! 596: ! 597: struct ! 598: { ! 599: int key; ! 600: int down; ! 601: } keyq[64]; ! 602: int keyq_head=0; ! 603: int keyq_tail=0; ! 604: ! 605: int config_notify=0; ! 606: int config_notify_width; ! 607: int config_notify_height; ! 608: ! 609: void GetEvent(void) ! 610: { ! 611: ! 612: XEvent x_event; ! 613: ! 614: XNextEvent(x_disp, &x_event); ! 615: switch(x_event.type) ! 616: { ! 617: case KeyPress: ! 618: keyq[keyq_head].key = XLateKey(&x_event.xkey); ! 619: keyq[keyq_head].down = true; ! 620: keyq_head = (keyq_head + 1) & 63; ! 621: break; ! 622: case KeyRelease: ! 623: keyq[keyq_head].key = XLateKey(&x_event.xkey); ! 624: keyq[keyq_head].down = false; ! 625: keyq_head = (keyq_head + 1) & 63; ! 626: break; ! 627: case ConfigureNotify: ! 628: // printf("config notify\n"); ! 629: config_notify_width = x_event.xconfigure.width; ! 630: config_notify_height = x_event.xconfigure.height; ! 631: config_notify = 1; ! 632: break; ! 633: default: ! 634: if (doShm && x_event.type == x_shmeventtype) ! 635: oktodraw = true; ! 636: } ! 637: ! 638: } ! 639: ! 640: // flushes the given rectangles from the view buffer to the screen ! 641: ! 642: void VID_Update (vrect_t *rects) ! 643: { ! 644: ! 645: // if the window changes dimension, skip this frame ! 646: ! 647: if (config_notify) ! 648: { ! 649: fprintf(stderr, "config notify\n"); ! 650: config_notify = 0; ! 651: vid.width = config_notify_width & ~7; ! 652: vid.height = config_notify_height; ! 653: if (doShm) ! 654: ResetSharedFrameBuffers(); ! 655: else ! 656: ResetFrameBuffer(); ! 657: vid.rowbytes = x_framebuffer[0]->bytes_per_line; ! 658: vid.buffer = x_framebuffer[current_framebuffer]->data; ! 659: vid.conbuffer = vid.buffer; ! 660: vid.conwidth = vid.width; ! 661: vid.conheight = vid.height; ! 662: vid.conrowbytes = vid.rowbytes; ! 663: vid.recalc_refdef = 1; // force a surface cache flush ! 664: Con_CheckResize(); ! 665: Con_Clear_f(); ! 666: return; ! 667: } ! 668: ! 669: if (doShm) ! 670: { ! 671: ! 672: while (rects) ! 673: { ! 674: if (!XShmPutImage(x_disp, x_win, x_gc, ! 675: x_framebuffer[current_framebuffer], rects->x, rects->y, ! 676: rects->x, rects->y, rects->width, rects->height, True)) ! 677: Sys_Error("VID_Update: XShmPutImage failed\n"); ! 678: oktodraw = false; ! 679: while (!oktodraw) GetEvent(); ! 680: rects = rects->pnext; ! 681: } ! 682: current_framebuffer = !current_framebuffer; ! 683: vid.buffer = x_framebuffer[current_framebuffer]->data; ! 684: vid.conbuffer = vid.buffer; ! 685: XSync(x_disp, False); ! 686: } ! 687: else ! 688: { ! 689: while (rects) ! 690: { ! 691: XPutImage(x_disp, x_win, x_gc, x_framebuffer[0], rects->x, ! 692: rects->y, rects->x, rects->y, rects->width, rects->height); ! 693: rects = rects->pnext; ! 694: } ! 695: XSync(x_disp, False); ! 696: } ! 697: ! 698: } ! 699: ! 700: static int dither; ! 701: ! 702: void VID_DitherOn(void) ! 703: { ! 704: if (dither == 0) ! 705: { ! 706: vid.recalc_refdef = 1; ! 707: dither = 1; ! 708: } ! 709: } ! 710: ! 711: void VID_DitherOff(void) ! 712: { ! 713: if (dither) ! 714: { ! 715: vid.recalc_refdef = 1; ! 716: dither = 0; ! 717: } ! 718: } ! 719: ! 720: int Sys_OpenWindow(void) ! 721: { ! 722: return 0; ! 723: } ! 724: ! 725: void Sys_EraseWindow(int window) ! 726: { ! 727: } ! 728: ! 729: void Sys_DrawCircle(int window, int x, int y, int r) ! 730: { ! 731: } ! 732: ! 733: void Sys_DisplayWindow(int window) ! 734: { ! 735: } ! 736: ! 737: void Sys_SendKeyEvents(void) ! 738: { ! 739: // get events from x server ! 740: if (x_disp) ! 741: { ! 742: while (XPending(x_disp)) GetEvent(); ! 743: while (keyq_head != keyq_tail) ! 744: { ! 745: Key_Event(keyq[keyq_tail].key, keyq[keyq_tail].down); ! 746: keyq_tail = (keyq_tail + 1) & 63; ! 747: } ! 748: } ! 749: } ! 750: ! 751: char *Sys_ConsoleInput (void) ! 752: { ! 753: ! 754: static char text[256]; ! 755: int len; ! 756: fd_set readfds; ! 757: int ready; ! 758: struct timeval timeout; ! 759: ! 760: timeout.tv_sec = 0; ! 761: timeout.tv_usec = 0; ! 762: FD_ZERO(&readfds); ! 763: FD_SET(0, &readfds); ! 764: ready = select(1, &readfds, 0, 0, &timeout); ! 765: ! 766: if (ready>0) ! 767: { ! 768: len = read (0, text, sizeof(text)); ! 769: if (len >= 1) ! 770: { ! 771: text[len-1] = 0; // rip off the /n and terminate ! 772: return text; ! 773: } ! 774: } ! 775: ! 776: return 0; ! 777: ! 778: } ! 779: ! 780: void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height) ! 781: { ! 782: // direct drawing of the "accessing disk" icon isn't supported under Linux ! 783: } ! 784: ! 785: void D_EndDirectRect (int x, int y, int width, int height) ! 786: { ! 787: // direct drawing of the "accessing disk" icon isn't supported under Linux ! 788: } ! 789:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.