Annotation of quake1/vid_op~1.c, revision 1.1.1.1

1.1       root        1: // vid_x.c -- general x video driver
                      2: 
                      3: #include <sys/time.h>
                      4: #include <sys/types.h>
                      5: #include <unistd.h>
                      6: #include <signal.h>
                      7: #include <stdlib.h>
                      8: #include <stdio.h>
                      9: #include <string.h>
                     10: #include <sys/ipc.h>
                     11: #include <sys/shm.h>
                     12: #include <X11/Xlib.h>
                     13: #include <X11/Xutil.h>
                     14: #include <X11/Xatom.h>
                     15: #include <X11/keysym.h>
                     16: #include <X11/extensions/XShm.h>
                     17: #include <GL/gl.h>
                     18: #include <GL/glx.h>
                     19: #include <GL/glu.h>
                     20: 
                     21: #include "quakedef.h"
                     22: #include "vid_256.h"
                     23: 
                     24: typedef struct
                     25: {
                     26:        int input;
                     27:        int output;
                     28: } keymap_t;
                     29: 
                     30: viddef_t vid; // global video state
                     31: 
                     32: int            num_shades=32;
                     33: 
                     34: static qboolean                        doShm;
                     35: static Display                 *x_disp;
                     36: static Colormap                        x_cmap;
                     37: static Window                  x_win;
                     38: static GC                              x_gc;
                     39: static Visual                  *x_vis;
                     40: static XVisualInfo             *x_visinfo=0;
                     41: //static XImage                        *x_image;
                     42: static int                             x_screen;
                     43: 
                     44: static int                             x_shmeventtype;
                     45: //static XShmSegmentInfo       x_shminfo;
                     46: 
                     47: static qboolean                        oktodraw = false;
                     48: 
                     49: static unsigned char   *framebuffer=0;
                     50: 
                     51: static int verbose=0;
                     52: 
                     53: static short *jcspace=0;
                     54: 
                     55: static qboolean                        doGLX;
                     56: static int glX_errorBase, glX_eventBase;
                     57: static GLXContext glX_context;
                     58: 
                     59: static qboolean                        glX_scaled=0;
                     60: static GLfloat                 glX_scale_width;
                     61: static GLfloat                 glX_scale_height;
                     62: 
                     63: static int config_notify=0;
                     64: static int config_notify_width;
                     65: static int config_notify_height;
                     66: 
                     67: int    d_con_indirect = 0;
                     68: 
                     69: void Scaled_f(void)
                     70: {
                     71:        config_notify = 1;
                     72:        glX_scaled = 1;
                     73: }
                     74: 
                     75: void UnScaled_f(void)
                     76: {
                     77:        config_notify = 1;
                     78:        glX_scaled = 0;
                     79: }
                     80: 
                     81: // ========================================================================
                     82: // Tragic death handler
                     83: // ========================================================================
                     84: 
                     85: void TragicDeath(int signal_num)
                     86: {
                     87:        XAutoRepeatOn(x_disp);
                     88:        XCloseDisplay(x_disp);
                     89:        I_Error("This death brought to you by the number %d\n", signal_num);
                     90: }
                     91: 
                     92: // ========================================================================
                     93: // makes a null cursor
                     94: // ========================================================================
                     95: 
                     96: static Cursor CreateNullCursor(Display *display, Window root)
                     97: {
                     98:     Pixmap cursormask; 
                     99:     XGCValues xgc;
                    100:     GC gc;
                    101:     XColor dummycolour;
                    102:     Cursor cursor;
                    103: 
                    104:     cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/);
                    105:     xgc.function = GXclear;
                    106:     gc =  XCreateGC(display, cursormask, GCFunction, &xgc);
                    107:     XFillRectangle(display, cursormask, gc, 0, 0, 1, 1);
                    108:     dummycolour.pixel = 0;
                    109:     dummycolour.red = 0;
                    110:     dummycolour.flags = 04;
                    111:     cursor = XCreatePixmapCursor(display, cursormask, cursormask,
                    112:           &dummycolour,&dummycolour, 0,0);
                    113:     XFreePixmap(display,cursormask);
                    114:     XFreeGC(display,gc);
                    115:     return cursor;
                    116: }
                    117: 
                    118: void ResetFrameBuffer(void)
                    119: {
                    120: 
                    121:        int mem;
                    122:        int pwidth;
                    123: 
                    124:        if (!glX_scaled)
                    125:        {
                    126: 
                    127:                if (framebuffer)
                    128:                        Z_Free(framebuffer);
                    129: 
                    130:                pwidth = 4;
                    131:                mem = vid.width*4 * vid.height;
                    132: 
                    133:                framebuffer = Z_Malloc(mem);
                    134: 
                    135:                vid.rowbytes = 2 * vid.width;
                    136:                if (jcspace) Z_Free(jcspace);
                    137:                jcspace = Z_Malloc(vid.rowbytes * vid.height);
                    138:                vid.buffer = (pixel_t *) jcspace;
                    139: 
                    140:                glViewport(0, 0, vid.width, vid.height);
                    141:                glMatrixMode(GL_PROJECTION);
                    142:                glLoadIdentity();
                    143:                gluOrtho2D(0, vid.width, 0, vid.height);
                    144:                glMatrixMode(GL_MODELVIEW);
                    145:                glLoadIdentity();
                    146: 
                    147:                glPixelZoom(1.0, -1.0);
                    148:                glRasterPos2i(0, vid.height);
                    149: 
                    150:        }
                    151:        else
                    152:        {
                    153:                glViewport(0, 0, config_notify_width, config_notify_height);
                    154:                glMatrixMode(GL_PROJECTION);
                    155:                glLoadIdentity();
                    156:                gluOrtho2D(0, config_notify_width, 0, config_notify_height);
                    157:                glMatrixMode(GL_MODELVIEW);
                    158:                glLoadIdentity();
                    159: 
                    160:                glX_scale_width = (float) config_notify_width / vid.width;
                    161:                glX_scale_height = (float) config_notify_height / vid.height;
                    162:                glPixelZoom(glX_scale_width, -glX_scale_height);
                    163: 
                    164:                glRasterPos2i(0, config_notify_height);
                    165: 
                    166:        }
                    167: 
                    168: }
                    169: 
                    170: int *lookup24;
                    171: 
                    172: void InitLookup24(unsigned char *pal)
                    173: {
                    174: 
                    175:        int intensity;
                    176:        int color;
                    177:        int r, g, b;
                    178: 
                    179:        lookup24 = Z_Malloc(VID_GRADES * 256 * 4);
                    180: 
                    181: // intensities go from 0 (bright) to VID_GRADES - 1 (dark)
                    182: 
                    183:        for (intensity = 0 ; intensity < VID_GRADES ; intensity++)
                    184:        {
                    185:                for (color = 0 ; color < 256 ; color++)
                    186:                {
                    187:                        r = pal[color*3] * (VID_GRADES - intensity) / VID_GRADES;
                    188:                        g = pal[color*3+1] * (VID_GRADES - intensity) / VID_GRADES;
                    189:                        b = pal[color*3+2] * (VID_GRADES - intensity) / VID_GRADES;
                    190:                        r = (r<<24) + (r<<16) + (r<<8) + r;
                    191:                        g = (g<<24) + (g<<16) + (g<<8) + g;
                    192:                        b = (b<<24) + (b<<16) + (b<<8) + b;
                    193:                        r = r & 0xff000000;
                    194:                        g = g & 0x00ff0000;
                    195:                        b = b & 0x0000ff00;
                    196:                        /*
                    197:                        r = r & x_visinfo->red_mask;
                    198:                        g = g & x_visinfo->green_mask;
                    199:                        b = b & x_visinfo->blue_mask;
                    200:                        */
                    201:                        lookup24[intensity * 256 + color] = r + g + b;
                    202:                }
                    203:        }
                    204: 
                    205: }
                    206: 
                    207: void JCSpaceTo24(void)
                    208: {
                    209: 
                    210:        int rowcount;
                    211:        int height;
                    212:        short *from;
                    213:        int *to;
                    214: 
                    215:        from = jcspace;
                    216:        to = (int*) framebuffer;
                    217: 
                    218:        for (height = vid.height ; height ; height--)
                    219:        {
                    220:                for (rowcount = vid.width ; rowcount ; rowcount--)
                    221:                {
                    222:                        *to = lookup24[*from];
                    223:                        from++;
                    224:                        to++;
                    225:                }
                    226:        }
                    227: 
                    228: }
                    229: 
                    230: void PickVisual(void)
                    231: {
                    232: 
                    233:        int attribList1[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 8,
                    234:                GLX_BLUE_SIZE, 8, GLX_GREEN_SIZE, 8, None };
                    235:        int attribList2[] = { GLX_RGBA, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8,
                    236:                GLX_BLUE_SIZE, 8, None };
                    237: 
                    238:        doGLX = glXQueryExtension(x_disp, &glX_errorBase, &glX_eventBase);
                    239:        if (!doGLX) I_Error("OpenGL not supported\n");
                    240: 
                    241:        x_visinfo = glXChooseVisual(x_disp, x_screen, attribList1);
                    242:        if (!x_visinfo)
                    243:                x_visinfo = glXChooseVisual(x_disp, x_screen, attribList2);
                    244:        else
                    245:                printf("double-buffered\n");
                    246:        if (!x_visinfo)
                    247:                I_Error("Could not chose an RGB visual.  Use X version.\n");
                    248:        else
                    249:                printf("single-buffered\n");
                    250: 
                    251: //     if (verbose)
                    252:        {
                    253:                printf("Using visualid %d:\n", (int)(x_visinfo->visualid));
                    254:                printf("        screen %d\n", x_visinfo->screen);
                    255:                printf("        red_mask 0x%x\n", (int)(x_visinfo->red_mask));
                    256:                printf("        green_mask 0x%x\n", (int)(x_visinfo->green_mask));
                    257:                printf("        blue_mask 0x%x\n", (int)(x_visinfo->blue_mask));
                    258:                printf("        colormap_size %d\n", x_visinfo->colormap_size);
                    259:                printf("        bits_per_rgb %d\n", x_visinfo->bits_per_rgb);
                    260:        }
                    261: 
                    262:        x_vis = x_visinfo->visual;
                    263: 
                    264: }
                    265: 
                    266: void CreateWindow(void)
                    267: {
                    268: 
                    269: // setup attributes for main window
                    270:        int attribmask = CWEventMask  | CWColormap | CWBorderPixel;
                    271:        XSetWindowAttributes attribs;
                    272:        Colormap tmpcmap;
                    273: 
                    274:        tmpcmap = XCreateColormap(x_disp, XRootWindow(x_disp,
                    275:                x_visinfo->screen), x_vis, AllocNone);
                    276: 
                    277:        attribs.event_mask = StructureNotifyMask | KeyPressMask
                    278:                | KeyReleaseMask | ExposureMask;
                    279:        attribs.border_pixel = 0;
                    280:        attribs.colormap = tmpcmap;
                    281: 
                    282: // create the main window
                    283:        x_win = XCreateWindow(  x_disp,
                    284:                XRootWindow(x_disp, x_visinfo->screen),
                    285:                0, 0,   // x, y
                    286:                vid.width, vid.height,
                    287:                0, // borderwidth
                    288:                x_visinfo->depth,
                    289:                InputOutput,
                    290:                x_vis,
                    291:                attribmask,
                    292:                &attribs );
                    293: 
                    294:        XFreeColormap(x_disp, tmpcmap);
                    295: 
                    296: }
                    297: 
                    298: // Called at startup to set up translation tables, takes 256 8 bit RGB values
                    299: // the palette data will go away after the call, so it must be copied off if
                    300: // the video driver will need it again
                    301: 
                    302: void   VID_Init (unsigned char *palette)
                    303: {
                    304: 
                    305:        int pnum, i;
                    306:        int num_visuals;
                    307: 
                    308:        Cmd_AddCommand("glx_scaled", Scaled_f);
                    309:        Cmd_AddCommand("glx_unscaled", UnScaled_f);
                    310: 
                    311:        vid.width = 320;
                    312:        vid.height = 200;
                    313:        vid.aspect = 1.0;
                    314:        vid.numpages = 1;
                    315: 
                    316:        srandom(getpid());
                    317: 
                    318:        verbose=COM_CheckParm("-verbose");
                    319: 
                    320: // open the display
                    321:        x_disp = XOpenDisplay(0);
                    322:        if (!x_disp)
                    323:        {
                    324:                if (getenv("DISPLAY"))
                    325:                        I_Error("VID: Could not open display [%s]\n",
                    326:                                getenv("DISPLAY"));
                    327:                else
                    328:                        I_Error("VID: Could not open local display\n");
                    329:        }
                    330: 
                    331:        x_screen = DefaultScreen(x_disp);
                    332: 
                    333: // catch signals so i can turn on auto-repeat
                    334: 
                    335:        {
                    336:                struct sigaction sa;
                    337:                sigaction(SIGINT, 0, &sa);
                    338:                sa.sa_handler = TragicDeath;
                    339:                sigaction(SIGINT, &sa, 0);
                    340:                sigaction(SIGTERM, &sa, 0);
                    341:        }
                    342: 
                    343:        XAutoRepeatOff(x_disp);
                    344: 
                    345: // for debugging only
                    346:        XSynchronize(x_disp, True);
                    347: 
                    348: // check for command-line window size
                    349:        if ((pnum=COM_CheckParm("-winsize")))
                    350:        {
                    351:                if (pnum >= com_argc-2)
                    352:                        I_Error("VID: -winsize <width> <height>\n");
                    353:                vid.width = Q_atoi(com_argv[pnum+1]);
                    354:                vid.height = Q_atoi(com_argv[pnum+2]);
                    355:                if (!vid.width || !vid.height)
                    356:                        I_Error("VID: Bad window width/height\n");
                    357:        }
                    358: 
                    359:        PickVisual();
                    360: 
                    361:        CreateWindow();
                    362: 
                    363:        glX_context = glXCreateContext(x_disp, x_visinfo, 0, True);
                    364:        glXMakeCurrent(x_disp, x_win, glX_context);
                    365:        glPixelZoom(1.0, -1.0);
                    366: 
                    367: // create the GC
                    368:        {
                    369:                XGCValues xgcvalues;
                    370:                int valuemask = GCGraphicsExposures;
                    371:                xgcvalues.graphics_exposures = False;
                    372:                x_gc = XCreateGC(x_disp, x_win, valuemask, &xgcvalues );
                    373:        }
                    374: 
                    375:        InitLookup24(palette);
                    376: 
                    377: // inviso cursor
                    378:        XDefineCursor(x_disp, x_win, CreateNullCursor(x_disp, x_win));
                    379: 
                    380: // map the window
                    381:        XMapWindow(x_disp, x_win);
                    382: 
                    383: // wait for first exposure event
                    384:        {
                    385:                XEvent event;
                    386:                do
                    387:                {
                    388:                        XNextEvent(x_disp, &event);
                    389:                        if (event.type == Expose && !event.xexpose.count)
                    390:                                oktodraw = true;
                    391:                } while (!oktodraw);
                    392:        }
                    393: // now safe to draw
                    394: 
                    395:        ResetFrameBuffer();
                    396: 
                    397:        XSynchronize(x_disp, False);
                    398: 
                    399: }
                    400: 
                    401: void VID_SetPalette(unsigned char *palette)
                    402: {
                    403: 
                    404:        if (lookup24)
                    405:                Z_Free(lookup24);
                    406:        InitLookup24(palette);
                    407: 
                    408: }
                    409: 
                    410: // Called at shutdown
                    411: 
                    412: void   VID_Shutdown (void)
                    413: {
                    414:        I_Printf("VID_Shutdown\n");
                    415:        XAutoRepeatOn(x_disp);
                    416:        XCloseDisplay(x_disp);
                    417: }
                    418: 
                    419: int XLateKey(XKeyEvent *ev)
                    420: {
                    421: 
                    422:        int key;
                    423:        char buf[64];
                    424:        KeySym keysym;
                    425: 
                    426:        XLookupString(ev, buf, sizeof buf, &keysym, 0);
                    427: 
                    428:        switch(keysym)
                    429:        {
                    430:                case XK_Left:    key = K_LEFTARROW; break;
                    431:                case XK_Right:  key = K_RIGHTARROW;             break;
                    432:                case XK_Down:    key = K_DOWNARROW; break;
                    433:                case XK_Up:              key = K_UPARROW;        break;
                    434:                case XK_Escape: key = K_ESCAPE;         break;
                    435:                case XK_Return: key = K_ENTER;           break;
                    436:                case XK_Tab:            key = K_TAB;                     break;
                    437:                case XK_F1:              key = K_F1;                            break;
                    438:                case XK_F2:              key = K_F2;                            break;
                    439:                case XK_F3:              key = K_F3;                            break;
                    440:                case XK_F4:              key = K_F4;                            break;
                    441:                case XK_F5:              key = K_F5;                            break;
                    442:                case XK_F6:              key = K_F6;                            break;
                    443:                case XK_F7:              key = K_F7;                            break;
                    444:                case XK_F8:              key = K_F8;                            break;
                    445:                case XK_F9:              key = K_F9;                            break;
                    446:                case XK_F10:            key = K_F10;                     break;
                    447:                case XK_F11:            key = K_F11;                     break;
                    448:                case XK_F12:            key = K_F12;                     break;
                    449:                case XK_BackSpace:
                    450:                case XK_Delete: key = K_BACKSPACE; break;
                    451:                case XK_Pause:  key = K_PAUSE;           break;
                    452:                case XK_Shift_L:
                    453:                case XK_Shift_R:                key = K_SHIFT;          break;
                    454:                case XK_Control_L: 
                    455:                case XK_Control_R:      key = K_CTRL;            break;
                    456:                case XK_Alt_L:  
                    457:                case XK_Meta_L: 
                    458:                case XK_Alt_R:  
                    459:                case XK_Meta_R: key = K_ALT;                    break;
                    460:                default:
                    461:                        key = *buf;
                    462:                        break;
                    463:        } 
                    464: 
                    465:        return key;
                    466: 
                    467: }
                    468: 
                    469: void GetEvent(void)
                    470: {
                    471: 
                    472:        XEvent x_event;
                    473: 
                    474:        XNextEvent(x_disp, &x_event);
                    475:        switch(x_event.type)
                    476:        {
                    477:                case KeyPress:
                    478:                        Key_Event(XLateKey(&x_event.xkey), true);
                    479:                        break;
                    480:                case KeyRelease:
                    481:                        Key_Event(XLateKey(&x_event.xkey), false);
                    482:                        break;
                    483:                case ConfigureNotify:
                    484: //                     printf("config notify\n");
                    485:                        config_notify_width = x_event.xconfigure.width;
                    486:                        config_notify_height = x_event.xconfigure.height;
                    487:                        config_notify = 1;
                    488:                        break;
                    489:        }
                    490: 
                    491: }
                    492: 
                    493: // flushes the given rectangles from the view buffer to the screen
                    494: 
                    495: void   VID_Update (vrect_t *rects)
                    496: {
                    497: 
                    498: // if the window changes dimension, skip this frame
                    499: 
                    500:        if (config_notify)
                    501:        {
                    502:                printf("config notify\n");
                    503:                config_notify = 0;
                    504:                if (!glX_scaled)
                    505:                {
                    506:                        vid.width = config_notify_width & ~3;
                    507:                        vid.height = config_notify_height;
                    508:                }
                    509:                ResetFrameBuffer();
                    510:                return;
                    511:        }
                    512: 
                    513: // slam that baby
                    514: 
                    515:        JCSpaceTo24();
                    516:        glDrawPixels(vid.width, vid.height, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer);
                    517:        glFlush();
                    518:        glXSwapBuffers(x_disp, x_win);
                    519: 
                    520: }
                    521: 
                    522: static int dither;
                    523: 
                    524: void VID_DitherOn(void)
                    525: {
                    526:     if (dither == 0)
                    527:     {
                    528:                vid.recalc_refdef = 1;
                    529:         dither = 1;
                    530:     }
                    531: }
                    532: 
                    533: void VID_DitherOff(void)
                    534: {
                    535:     if (dither)
                    536:     {
                    537:                vid.recalc_refdef = 1;
                    538:         dither = 0;
                    539:     }
                    540: }
                    541: 
                    542: int I_OpenWindow(void)
                    543: {
                    544:        return 0;
                    545: }
                    546: 
                    547: void I_EraseWindow(int window)
                    548: {
                    549: }
                    550: 
                    551: void I_DrawCircle(int window, int x, int y, int r)
                    552: {
                    553: }
                    554: 
                    555: void I_DisplayWindow(int window)
                    556: {
                    557: }
                    558: 
                    559: void Sys_SendKeyEvents(void)
                    560: {
                    561: // get events from x server
                    562:        while (XPending(x_disp)) GetEvent();
                    563: }
                    564: 
                    565: char *Sys_ConsoleInput (void)
                    566: {
                    567: 
                    568:        static char     text[256];
                    569:        int             len;
                    570:        fd_set  readfds;
                    571:        int             ready;
                    572:        struct timeval timeout;
                    573: 
                    574:        timeout.tv_sec = 0;
                    575:        timeout.tv_usec = 0;
                    576:        FD_ZERO(&readfds);
                    577:        FD_SET(0, &readfds);
                    578:        ready = select(1, &readfds, 0, 0, &timeout);
                    579: 
                    580:        if (ready>0)
                    581:        {
                    582:                len = read (0, text, sizeof(text));
                    583:                if (len >= 1)
                    584:                {
                    585:                        text[len-1] = 0;        // rip off the /n and terminate
                    586:                        return text;
                    587:                }
                    588:        }
                    589: 
                    590:        return 0;
                    591:        
                    592: }
                    593: 

unix.superglobalmegacorp.com

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