Annotation of quake1/vid_op~1.c, revision 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.