Annotation of quake1/vid_x.c, revision 1.1.1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.