Annotation of quake2/linux/rw_x11.c, revision 1.1.1.2

1.1       root        1: /*
1.1.1.2 ! root        2: Copyright (C) 1997-2001 Id Software, Inc.
        !             3: 
        !             4: This program is free software; you can redistribute it and/or
        !             5: modify it under the terms of the GNU General Public License
        !             6: as published by the Free Software Foundation; either version 2
        !             7: of the License, or (at your option) any later version.
        !             8: 
        !             9: This program is distributed in the hope that it will be useful,
        !            10: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
        !            12: 
        !            13: See the GNU General Public License for more details.
        !            14: 
        !            15: You should have received a copy of the GNU General Public License
        !            16: along with this program; if not, write to the Free Software
        !            17: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
        !            18: 
        !            19: */
        !            20: /*
1.1       root       21: ** RW_X11.C
                     22: **
                     23: ** This file contains ALL Linux specific stuff having to do with the
                     24: ** software refresh.  When a port is being made the following functions
                     25: ** must be implemented by the port:
                     26: **
                     27: ** SWimp_EndFrame
                     28: ** SWimp_Init
                     29: ** SWimp_InitGraphics
                     30: ** SWimp_SetPalette
                     31: ** SWimp_Shutdown
                     32: ** SWimp_SwitchFullscreen
                     33: */
                     34: 
                     35: #include <ctype.h>
                     36: #include <sys/time.h>
                     37: #include <sys/types.h>
                     38: #include <unistd.h>
                     39: #include <signal.h>
                     40: #include <stdlib.h>
                     41: #include <stdio.h>
                     42: #include <string.h>
                     43: #include <sys/ipc.h>
                     44: #include <sys/shm.h>
                     45: 
                     46: #include <X11/Xlib.h>
                     47: #include <X11/Xutil.h>
                     48: #include <X11/Xatom.h>
                     49: #include <X11/keysym.h>
                     50: #include <X11/extensions/XShm.h>
1.1.1.2 ! root       51: #include <X11/extensions/xf86dga.h>
1.1       root       52: 
                     53: #include "../ref_soft/r_local.h"
                     54: #include "../client/keys.h"
                     55: #include "../linux/rw_linux.h"
                     56: 
                     57: /*****************************************************************************/
                     58: 
                     59: static qboolean                        doShm;
1.1.1.2 ! root       60: static Display                 *dpy;
1.1       root       61: static Colormap                        x_cmap;
1.1.1.2 ! root       62: static Window                  win;
1.1       root       63: static GC                              x_gc;
                     64: static Visual                  *x_vis;
                     65: static XVisualInfo             *x_visinfo;
1.1.1.2 ! root       66: static int win_x, win_y;
1.1       root       67: 
1.1.1.2 ! root       68: #define KEY_MASK (KeyPressMask | KeyReleaseMask)
        !            69: #define MOUSE_MASK (ButtonPressMask | ButtonReleaseMask | \
        !            70:                    PointerMotionMask | ButtonMotionMask )
        !            71: #define X_MASK (KEY_MASK | MOUSE_MASK | VisibilityChangeMask | StructureNotifyMask | ExposureMask )
1.1       root       72: 
                     73: static int                             x_shmeventtype;
                     74: //static XShmSegmentInfo       x_shminfo;
                     75: 
                     76: static qboolean                        oktodraw = false;
1.1.1.2 ! root       77: static qboolean                        ignorefirst = false;
        !            78: static qboolean                        exposureflag = false;
1.1       root       79: static qboolean                        X11_active = false;
                     80: 
                     81: int XShmQueryExtension(Display *);
                     82: int XShmGetEventBase(Display *);
                     83: 
                     84: int current_framebuffer;
                     85: static XImage                  *x_framebuffer[2] = { 0, 0 };
                     86: static XShmSegmentInfo x_shminfo[2];
                     87: 
                     88: int config_notify=0;
                     89: int config_notify_width;
                     90: int config_notify_height;
                     91:                                                      
1.1.1.2 ! root       92: typedef unsigned short PIXEL16;
        !            93: typedef unsigned long PIXEL24;
        !            94: static PIXEL16 st2d_8to16table[256];
        !            95: static PIXEL24 st2d_8to24table[256];
        !            96: static int shiftmask_fl=0;
        !            97: static long r_shift,g_shift,b_shift;
        !            98: static unsigned long r_mask,g_mask,b_mask;
        !            99: 
        !           100: void shiftmask_init(void)
        !           101: {
        !           102:     unsigned int x;
        !           103:     r_mask=x_vis->red_mask;
        !           104:     g_mask=x_vis->green_mask;
        !           105:     b_mask=x_vis->blue_mask;
        !           106:     for(r_shift=-8,x=1;x<r_mask;x=x<<1)r_shift++;
        !           107:     for(g_shift=-8,x=1;x<g_mask;x=x<<1)g_shift++;
        !           108:     for(b_shift=-8,x=1;x<b_mask;x=x<<1)b_shift++;
        !           109:     shiftmask_fl=1;
        !           110: }
        !           111: 
        !           112: PIXEL16 xlib_rgb16(int r,int g,int b)
        !           113: {
        !           114:     PIXEL16 p;
        !           115:     if(shiftmask_fl==0) shiftmask_init();
        !           116:     p=0;
        !           117: 
        !           118:     if(r_shift>0) {
        !           119:         p=(r<<(r_shift))&r_mask;
        !           120:     } else if(r_shift<0) {
        !           121:         p=(r>>(-r_shift))&r_mask;
        !           122:     } else p|=(r&r_mask);
        !           123: 
        !           124:     if(g_shift>0) {
        !           125:         p|=(g<<(g_shift))&g_mask;
        !           126:     } else if(g_shift<0) {
        !           127:         p|=(g>>(-g_shift))&g_mask;
        !           128:     } else p|=(g&g_mask);
        !           129: 
        !           130:     if(b_shift>0) {
        !           131:         p|=(b<<(b_shift))&b_mask;
        !           132:     } else if(b_shift<0) {
        !           133:         p|=(b>>(-b_shift))&b_mask;
        !           134:     } else p|=(b&b_mask);
        !           135: 
        !           136:     return p;
        !           137: }
        !           138: 
        !           139: PIXEL24 xlib_rgb24(int r,int g,int b)
        !           140: {
        !           141:     PIXEL24 p;
        !           142:     if(shiftmask_fl==0) shiftmask_init();
        !           143:     p=0;
        !           144: 
        !           145:     if(r_shift>0) {
        !           146:         p=(r<<(r_shift))&r_mask;
        !           147:     } else if(r_shift<0) {
        !           148:         p=(r>>(-r_shift))&r_mask;
        !           149:     } else p|=(r&r_mask);
        !           150: 
        !           151:     if(g_shift>0) {
        !           152:         p|=(g<<(g_shift))&g_mask;
        !           153:     } else if(g_shift<0) {
        !           154:         p|=(g>>(-g_shift))&g_mask;
        !           155:     } else p|=(g&g_mask);
        !           156: 
        !           157:     if(b_shift>0) {
        !           158:         p|=(b<<(b_shift))&b_mask;
        !           159:     } else if(b_shift<0) {
        !           160:         p|=(b>>(-b_shift))&b_mask;
        !           161:     } else p|=(b&b_mask);
        !           162: 
        !           163:     return p;
        !           164: }
        !           165: 
        !           166: 
        !           167: void st2_fixup( XImage *framebuf, int x, int y, int width, int height)
        !           168: {
        !           169:        int xi,yi;
        !           170:        unsigned char *src;
        !           171:        PIXEL16 *dest;
        !           172:        register int count, n;
        !           173: 
        !           174:        if( (x<0)||(y<0) )return;
        !           175: 
        !           176:        for (yi = y; yi < (y+height); yi++) {
        !           177:                src = &framebuf->data [yi * framebuf->bytes_per_line];
        !           178: 
        !           179:                // Duff's Device
        !           180:                count = width;
        !           181:                n = (count + 7) / 8;
        !           182:                dest = ((PIXEL16 *)src) + x+width - 1;
        !           183:                src += x+width - 1;
        !           184: 
        !           185:                switch (count % 8) {
        !           186:                case 0: do {    *dest-- = st2d_8to16table[*src--];
        !           187:                case 7:                 *dest-- = st2d_8to16table[*src--];
        !           188:                case 6:                 *dest-- = st2d_8to16table[*src--];
        !           189:                case 5:                 *dest-- = st2d_8to16table[*src--];
        !           190:                case 4:                 *dest-- = st2d_8to16table[*src--];
        !           191:                case 3:                 *dest-- = st2d_8to16table[*src--];
        !           192:                case 2:                 *dest-- = st2d_8to16table[*src--];
        !           193:                case 1:                 *dest-- = st2d_8to16table[*src--];
        !           194:                                } while (--n > 0);
        !           195:                }
        !           196: 
        !           197: //             for(xi = (x+width-1); xi >= x; xi--) {
        !           198: //                     dest[xi] = st2d_8to16table[src[xi]];
        !           199: //             }
        !           200:        }
        !           201: }
        !           202: 
        !           203: void st3_fixup( XImage *framebuf, int x, int y, int width, int height)
        !           204: {
        !           205:        int xi,yi;
        !           206:        unsigned char *src;
        !           207:        PIXEL24 *dest;
        !           208:        register int count, n;
        !           209: 
        !           210:        if( (x<0)||(y<0) )return;
        !           211: 
        !           212:        for (yi = y; yi < (y+height); yi++) {
        !           213:                src = &framebuf->data [yi * framebuf->bytes_per_line];
        !           214: 
        !           215:                // Duff's Device
        !           216:                count = width;
        !           217:                n = (count + 7) / 8;
        !           218:                dest = ((PIXEL24 *)src) + x+width - 1;
        !           219:                src += x+width - 1;
        !           220: 
        !           221:                switch (count % 8) {
        !           222:                case 0: do {    *dest-- = st2d_8to24table[*src--];
        !           223:                case 7:                 *dest-- = st2d_8to24table[*src--];
        !           224:                case 6:                 *dest-- = st2d_8to24table[*src--];
        !           225:                case 5:                 *dest-- = st2d_8to24table[*src--];
        !           226:                case 4:                 *dest-- = st2d_8to24table[*src--];
        !           227:                case 3:                 *dest-- = st2d_8to24table[*src--];
        !           228:                case 2:                 *dest-- = st2d_8to24table[*src--];
        !           229:                case 1:                 *dest-- = st2d_8to24table[*src--];
        !           230:                                } while (--n > 0);
        !           231:                }
        !           232: 
        !           233: //             for(xi = (x+width-1); xi >= x; xi--) {
        !           234: //                     dest[xi] = st2d_8to16table[src[xi]];
        !           235: //             }
        !           236:        }
        !           237: }
        !           238: 
        !           239: 
1.1       root      240: 
                    241: // Console variables that we need to access from this module
                    242: 
                    243: /*****************************************************************************/
                    244: /* MOUSE                                                                     */
                    245: /*****************************************************************************/
                    246: 
                    247: // this is inside the renderer shared lib, so these are called from vid_so
                    248: 
1.1.1.2 ! root      249: static qboolean        mouse_avail;
        !           250: static int             mouse_buttonstate;
        !           251: static int             mouse_oldbuttonstate;
        !           252: static int             old_mouse_x, old_mouse_y;
1.1       root      253: static int             mx, my;
                    254: 
1.1.1.2 ! root      255: static qboolean mouse_active = false;
        !           256: static qboolean dgamouse = false;
        !           257: 
1.1       root      258: static cvar_t  *m_filter;
                    259: static cvar_t  *in_mouse;
1.1.1.2 ! root      260: static cvar_t  *in_dgamouse;
        !           261: 
        !           262: static cvar_t  *vid_xpos;                      // X coordinate of window position
        !           263: static cvar_t  *vid_ypos;                      // Y coordinate of window position
1.1       root      264: 
                    265: static qboolean        mlooking;
                    266: 
                    267: // state struct passed in Init
                    268: static in_state_t      *in_state;
                    269: 
                    270: static cvar_t *sensitivity;
                    271: static cvar_t *lookstrafe;
                    272: static cvar_t *m_side;
                    273: static cvar_t *m_yaw;
                    274: static cvar_t *m_pitch;
                    275: static cvar_t *m_forward;
                    276: static cvar_t *freelook;
                    277: 
                    278: static void Force_CenterView_f (void)
                    279: {
                    280:        in_state->viewangles[PITCH] = 0;
                    281: }
                    282: 
                    283: static void RW_IN_MLookDown (void) 
                    284: { 
                    285:        mlooking = true; 
                    286: }
                    287: 
                    288: static void RW_IN_MLookUp (void) 
                    289: {
                    290:        mlooking = false;
                    291:        in_state->IN_CenterView_fp ();
                    292: }
                    293: 
                    294: void RW_IN_Init(in_state_t *in_state_p)
                    295: {
                    296:        int mtype;
                    297:        int i;
                    298: 
                    299:        in_state = in_state_p;
                    300: 
                    301:        // mouse variables
                    302:        m_filter = ri.Cvar_Get ("m_filter", "0", 0);
1.1.1.2 ! root      303:     in_mouse = ri.Cvar_Get ("in_mouse", "0", CVAR_ARCHIVE);
        !           304:     in_dgamouse = ri.Cvar_Get ("in_dgamouse", "1", CVAR_ARCHIVE);
1.1       root      305:        freelook = ri.Cvar_Get( "freelook", "0", 0 );
                    306:        lookstrafe = ri.Cvar_Get ("lookstrafe", "0", 0);
                    307:        sensitivity = ri.Cvar_Get ("sensitivity", "3", 0);
                    308:        m_pitch = ri.Cvar_Get ("m_pitch", "0.022", 0);
                    309:        m_yaw = ri.Cvar_Get ("m_yaw", "0.022", 0);
                    310:        m_forward = ri.Cvar_Get ("m_forward", "1", 0);
                    311:        m_side = ri.Cvar_Get ("m_side", "0.8", 0);
                    312: 
                    313:        ri.Cmd_AddCommand ("+mlook", RW_IN_MLookDown);
                    314:        ri.Cmd_AddCommand ("-mlook", RW_IN_MLookUp);
                    315: 
                    316:        ri.Cmd_AddCommand ("force_centerview", Force_CenterView_f);
                    317: 
                    318:        mouse_avail = true;
                    319: }
                    320: 
                    321: void RW_IN_Shutdown(void)
                    322: {
                    323:        mouse_avail = false;
                    324: }
                    325: 
                    326: /*
                    327: ===========
                    328: IN_Commands
                    329: ===========
                    330: */
                    331: void RW_IN_Commands (void)
                    332: {
                    333:        int i;
                    334:    
                    335:        if (!mouse_avail) 
                    336:                return;
                    337:    
                    338:        for (i=0 ; i<3 ; i++) {
                    339:                if ( (mouse_buttonstate & (1<<i)) && !(mouse_oldbuttonstate & (1<<i)) )
                    340:                        in_state->Key_Event_fp (K_MOUSE1 + i, true);
                    341: 
                    342:                if ( !(mouse_buttonstate & (1<<i)) && (mouse_oldbuttonstate & (1<<i)) )
                    343:                        in_state->Key_Event_fp (K_MOUSE1 + i, false);
                    344:        }
                    345:        mouse_oldbuttonstate = mouse_buttonstate;
                    346: }
                    347: 
                    348: /*
                    349: ===========
                    350: IN_Move
                    351: ===========
                    352: */
                    353: void RW_IN_Move (usercmd_t *cmd)
                    354: {
                    355:        if (!mouse_avail)
                    356:                return;
                    357:    
                    358:        if (m_filter->value)
                    359:        {
1.1.1.2 ! root      360:                mx = (mx + old_mouse_x) * 0.5;
        !           361:                my = (my + old_mouse_y) * 0.5;
1.1       root      362:        }
                    363: 
                    364:        old_mouse_x = mx;
                    365:        old_mouse_y = my;
                    366: 
1.1.1.2 ! root      367:        mx *= sensitivity->value;
        !           368:        my *= sensitivity->value;
1.1       root      369: 
                    370: // add mouse X/Y movement to cmd
                    371:        if ( (*in_state->in_strafe_state & 1) || 
                    372:                (lookstrafe->value && mlooking ))
1.1.1.2 ! root      373:                cmd->sidemove += m_side->value * mx;
1.1       root      374:        else
1.1.1.2 ! root      375:                in_state->viewangles[YAW] -= m_yaw->value * mx;
1.1       root      376: 
                    377:        if ( (mlooking || freelook->value) && 
                    378:                !(*in_state->in_strafe_state & 1))
                    379:        {
1.1.1.2 ! root      380:                in_state->viewangles[PITCH] += m_pitch->value * my;
1.1       root      381:        }
                    382:        else
                    383:        {
1.1.1.2 ! root      384:                cmd->forwardmove -= m_forward->value * my;
1.1       root      385:        }
                    386:        mx = my = 0;
                    387: }
                    388: 
                    389: // ========================================================================
                    390: // makes a null cursor
                    391: // ========================================================================
                    392: 
                    393: static Cursor CreateNullCursor(Display *display, Window root)
                    394: {
                    395:     Pixmap cursormask; 
                    396:     XGCValues xgc;
                    397:     GC gc;
                    398:     XColor dummycolour;
                    399:     Cursor cursor;
                    400: 
                    401:     cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/);
                    402:     xgc.function = GXclear;
                    403:     gc =  XCreateGC(display, cursormask, GCFunction, &xgc);
                    404:     XFillRectangle(display, cursormask, gc, 0, 0, 1, 1);
                    405:     dummycolour.pixel = 0;
                    406:     dummycolour.red = 0;
                    407:     dummycolour.flags = 04;
                    408:     cursor = XCreatePixmapCursor(display, cursormask, cursormask,
                    409:           &dummycolour,&dummycolour, 0,0);
                    410:     XFreePixmap(display,cursormask);
                    411:     XFreeGC(display,gc);
                    412:     return cursor;
                    413: }
                    414: 
1.1.1.2 ! root      415: static void install_grabs(void)
        !           416: {
        !           417: 
        !           418: // inviso cursor
        !           419:        XDefineCursor(dpy, win, CreateNullCursor(dpy, win));
        !           420: 
        !           421:        XGrabPointer(dpy, win,
        !           422:                                 True,
        !           423:                                 0,
        !           424:                                 GrabModeAsync, GrabModeAsync,
        !           425:                                 win,
        !           426:                                 None,
        !           427:                                 CurrentTime);
        !           428: 
        !           429:        if (in_dgamouse->value) {
        !           430:                int MajorVersion, MinorVersion;
        !           431: 
        !           432:                if (!XF86DGAQueryVersion(dpy, &MajorVersion, &MinorVersion)) { 
        !           433:                        // unable to query, probalby not supported
        !           434:                        ri.Con_Printf( PRINT_ALL, "Failed to detect XF86DGA Mouse\n" );
        !           435:                        ri.Cvar_Set( "in_dgamouse", "0" );
        !           436:                } else {
        !           437:                        dgamouse = true;
        !           438:                        XF86DGADirectVideo(dpy, DefaultScreen(dpy), XF86DGADirectMouse);
        !           439:                        XWarpPointer(dpy, None, win, 0, 0, 0, 0, 0, 0);
        !           440:                }
        !           441:        } else
        !           442:                XWarpPointer(dpy, None, win, 0, 0, 0, 0, vid.width / 2, vid.height / 2);
        !           443: 
        !           444:        XGrabKeyboard(dpy, win,
        !           445:                                  False,
        !           446:                                  GrabModeAsync, GrabModeAsync,
        !           447:                                  CurrentTime);
        !           448: 
        !           449:        mouse_active = true;
        !           450: 
        !           451:        ignorefirst = true;
        !           452: 
        !           453: //     XSync(dpy, True);
        !           454: }
        !           455: 
        !           456: static void uninstall_grabs(void)
        !           457: {
        !           458:        if (!dpy || !win)
        !           459:                return;
        !           460: 
        !           461:        if (dgamouse) {
        !           462:                dgamouse = false;
        !           463:                XF86DGADirectVideo(dpy, DefaultScreen(dpy), 0);
        !           464:        }
        !           465: 
        !           466:        XUngrabPointer(dpy, CurrentTime);
        !           467:        XUngrabKeyboard(dpy, CurrentTime);
        !           468: 
        !           469: // inviso cursor
        !           470:        XUndefineCursor(dpy, win);
        !           471: 
        !           472:        mouse_active = false;
        !           473: }
        !           474: 
        !           475: static void IN_DeactivateMouse( void ) 
        !           476: {
        !           477:        if (!mouse_avail || !dpy || !win)
        !           478:                return;
        !           479: 
        !           480:        if (mouse_active) {
        !           481:                uninstall_grabs();
        !           482:                mouse_active = false;
        !           483:        }
        !           484: }
        !           485: 
        !           486: static void IN_ActivateMouse( void ) 
        !           487: {
        !           488:        if (!mouse_avail || !dpy || !win)
        !           489:                return;
        !           490: 
        !           491:        if (!mouse_active) {
        !           492:                mx = my = 0; // don't spazz
        !           493:                install_grabs();
        !           494:                mouse_active = true;
        !           495:        }
        !           496: }
        !           497: 
        !           498: void RW_IN_Frame (void)
        !           499: {
        !           500: }
        !           501: 
        !           502: void RW_IN_Activate(qboolean active)
        !           503: {
        !           504:        if (active)
        !           505:                IN_ActivateMouse();
        !           506:        else
        !           507:                IN_DeactivateMouse ();
        !           508: }
        !           509: 
        !           510: /*****************************************************************************/
        !           511: 
1.1       root      512: void ResetFrameBuffer(void)
                    513: {
                    514:        int mem;
                    515:        int pwidth;
                    516: 
                    517:        if (x_framebuffer[0])
                    518:        {
                    519:                free(x_framebuffer[0]->data);
                    520:                free(x_framebuffer[0]);
                    521:        }
                    522: 
                    523: // alloc an extra line in case we want to wrap, and allocate the z-buffer
                    524:        pwidth = x_visinfo->depth / 8;
                    525:        if (pwidth == 3) pwidth = 4;
                    526:        mem = ((vid.width*pwidth+7)&~7) * vid.height;
                    527: 
1.1.1.2 ! root      528:        x_framebuffer[0] = XCreateImage(dpy,
1.1       root      529:                x_vis,
                    530:                x_visinfo->depth,
                    531:                ZPixmap,
                    532:                0,
                    533:                malloc(mem),
                    534:                vid.width, vid.height,
                    535:                32,
                    536:                0);
                    537: 
                    538:        if (!x_framebuffer[0])
                    539:                Sys_Error("VID: XCreateImage failed\n");
                    540: 
                    541:        vid.buffer = (byte*) (x_framebuffer[0]);
                    542: }
                    543: 
                    544: void ResetSharedFrameBuffers(void)
                    545: {
                    546:        int size;
                    547:        int key;
                    548:        int minsize = getpagesize();
                    549:        int frm;
                    550: 
                    551:        for (frm=0 ; frm<2 ; frm++)
                    552:        {
                    553:        // free up old frame buffer memory
                    554:                if (x_framebuffer[frm])
                    555:                {
1.1.1.2 ! root      556:                        XShmDetach(dpy, &x_shminfo[frm]);
1.1       root      557:                        free(x_framebuffer[frm]);
                    558:                        shmdt(x_shminfo[frm].shmaddr);
                    559:                }
                    560: 
                    561:        // create the image
1.1.1.2 ! root      562:                x_framebuffer[frm] = XShmCreateImage(   dpy,
1.1       root      563:                                                x_vis,
                    564:                                                x_visinfo->depth,
                    565:                                                ZPixmap,
                    566:                                                0,
                    567:                                                &x_shminfo[frm],
                    568:                                                vid.width,
                    569:                                                vid.height );
                    570: 
                    571:        // grab shared memory
                    572: 
                    573:                size = x_framebuffer[frm]->bytes_per_line
                    574:                        * x_framebuffer[frm]->height;
                    575:                if (size < minsize)
                    576:                        Sys_Error("VID: Window must use at least %d bytes\n", minsize);
                    577: 
                    578:                key = random();
                    579:                x_shminfo[frm].shmid = shmget((key_t)key, size, IPC_CREAT|0777);
                    580:                if (x_shminfo[frm].shmid==-1)
                    581:                        Sys_Error("VID: Could not get any shared memory\n");
                    582: 
                    583:                // attach to the shared memory segment
                    584:                x_shminfo[frm].shmaddr =
                    585:                        (void *) shmat(x_shminfo[frm].shmid, 0, 0);
                    586: 
1.1.1.2 ! root      587:                ri.Con_Printf(PRINT_DEVELOPER, "MITSHM shared memory (id=%d, addr=0x%lx)\n", 
        !           588:                        x_shminfo[frm].shmid, (long) x_shminfo[frm].shmaddr);
1.1       root      589: 
                    590:                x_framebuffer[frm]->data = x_shminfo[frm].shmaddr;
                    591: 
                    592:        // get the X server to attach to it
                    593: 
1.1.1.2 ! root      594:                if (!XShmAttach(dpy, &x_shminfo[frm]))
1.1       root      595:                        Sys_Error("VID: XShmAttach() failed\n");
1.1.1.2 ! root      596:                XSync(dpy, 0);
1.1       root      597:                shmctl(x_shminfo[frm].shmid, IPC_RMID, 0);
                    598:        }
                    599: 
                    600: }
                    601: 
                    602: // ========================================================================
                    603: // Tragic death handler
                    604: // ========================================================================
                    605: 
                    606: void TragicDeath(int signal_num)
                    607: {
1.1.1.2 ! root      608: //     XAutoRepeatOn(dpy);
        !           609:        XCloseDisplay(dpy);
1.1       root      610:        Sys_Error("This death brought to you by the number %d\n", signal_num);
                    611: }
                    612: 
                    613: int XLateKey(XKeyEvent *ev)
                    614: {
                    615: 
                    616:        int key;
                    617:        char buf[64];
                    618:        KeySym keysym;
                    619: 
                    620:        key = 0;
                    621: 
                    622:        XLookupString(ev, buf, sizeof buf, &keysym, 0);
                    623: 
                    624:        switch(keysym)
                    625:        {
                    626:                case XK_KP_Page_Up:      key = K_KP_PGUP; break;
                    627:                case XK_Page_Up:         key = K_PGUP; break;
                    628: 
                    629:                case XK_KP_Page_Down: key = K_KP_PGDN; break;
                    630:                case XK_Page_Down:       key = K_PGDN; break;
                    631: 
                    632:                case XK_KP_Home: key = K_KP_HOME; break;
                    633:                case XK_Home:    key = K_HOME; break;
                    634: 
                    635:                case XK_KP_End:  key = K_KP_END; break;
                    636:                case XK_End:     key = K_END; break;
                    637: 
                    638:                case XK_KP_Left: key = K_KP_LEFTARROW; break;
                    639:                case XK_Left:    key = K_LEFTARROW; break;
                    640: 
                    641:                case XK_KP_Right: key = K_KP_RIGHTARROW; break;
                    642:                case XK_Right:  key = K_RIGHTARROW;             break;
                    643: 
                    644:                case XK_KP_Down: key = K_KP_DOWNARROW; break;
                    645:                case XK_Down:    key = K_DOWNARROW; break;
                    646: 
                    647:                case XK_KP_Up:   key = K_KP_UPARROW; break;
                    648:                case XK_Up:              key = K_UPARROW;        break;
                    649: 
                    650:                case XK_Escape: key = K_ESCAPE;         break;
                    651: 
                    652:                case XK_KP_Enter: key = K_KP_ENTER;     break;
                    653:                case XK_Return: key = K_ENTER;           break;
                    654: 
                    655:                case XK_Tab:            key = K_TAB;                     break;
                    656: 
                    657:                case XK_F1:              key = K_F1;                            break;
                    658: 
                    659:                case XK_F2:              key = K_F2;                            break;
                    660: 
                    661:                case XK_F3:              key = K_F3;                            break;
                    662: 
                    663:                case XK_F4:              key = K_F4;                            break;
                    664: 
                    665:                case XK_F5:              key = K_F5;                            break;
                    666: 
                    667:                case XK_F6:              key = K_F6;                            break;
                    668: 
                    669:                case XK_F7:              key = K_F7;                            break;
                    670: 
                    671:                case XK_F8:              key = K_F8;                            break;
                    672: 
                    673:                case XK_F9:              key = K_F9;                            break;
                    674: 
                    675:                case XK_F10:            key = K_F10;                     break;
                    676: 
                    677:                case XK_F11:            key = K_F11;                     break;
                    678: 
                    679:                case XK_F12:            key = K_F12;                     break;
                    680: 
                    681:                case XK_BackSpace: key = K_BACKSPACE; break;
                    682: 
                    683:                case XK_KP_Delete: key = K_KP_DEL; break;
                    684:                case XK_Delete: key = K_DEL; break;
                    685: 
                    686:                case XK_Pause:  key = K_PAUSE;           break;
                    687: 
                    688:                case XK_Shift_L:
                    689:                case XK_Shift_R:        key = K_SHIFT;          break;
                    690: 
                    691:                case XK_Execute: 
                    692:                case XK_Control_L: 
                    693:                case XK_Control_R:      key = K_CTRL;            break;
                    694: 
                    695:                case XK_Alt_L:  
                    696:                case XK_Meta_L: 
                    697:                case XK_Alt_R:  
                    698:                case XK_Meta_R: key = K_ALT;                    break;
                    699: 
                    700:                case XK_KP_Begin: key = K_KP_5; break;
                    701: 
                    702:                case XK_Insert:key = K_INS; break;
                    703:                case XK_KP_Insert: key = K_KP_INS; break;
                    704: 
                    705:                case XK_KP_Multiply: key = '*'; break;
                    706:                case XK_KP_Add:  key = K_KP_PLUS; break;
                    707:                case XK_KP_Subtract: key = K_KP_MINUS; break;
                    708:                case XK_KP_Divide: key = K_KP_SLASH; break;
                    709: 
                    710: #if 0
                    711:                case 0x021: key = '1';break;/* [!] */
                    712:                case 0x040: key = '2';break;/* [@] */
                    713:                case 0x023: key = '3';break;/* [#] */
                    714:                case 0x024: key = '4';break;/* [$] */
                    715:                case 0x025: key = '5';break;/* [%] */
                    716:                case 0x05e: key = '6';break;/* [^] */
                    717:                case 0x026: key = '7';break;/* [&] */
                    718:                case 0x02a: key = '8';break;/* [*] */
                    719:                case 0x028: key = '9';;break;/* [(] */
                    720:                case 0x029: key = '0';break;/* [)] */
                    721:                case 0x05f: key = '-';break;/* [_] */
                    722:                case 0x02b: key = '=';break;/* [+] */
                    723:                case 0x07c: key = '\'';break;/* [|] */
                    724:                case 0x07d: key = '[';break;/* [}] */
                    725:                case 0x07b: key = ']';break;/* [{] */
                    726:                case 0x022: key = '\'';break;/* ["] */
                    727:                case 0x03a: key = ';';break;/* [:] */
                    728:                case 0x03f: key = '/';break;/* [?] */
                    729:                case 0x03e: key = '.';break;/* [>] */
                    730:                case 0x03c: key = ',';break;/* [<] */
                    731: #endif
                    732: 
                    733:                default:
                    734:                        key = *(unsigned char*)buf;
                    735:                        if (key >= 'A' && key <= 'Z')
                    736:                                key = key - 'A' + 'a';
                    737:                        break;
                    738:        } 
                    739: 
                    740:        return key;
                    741: }
                    742: 
1.1.1.2 ! root      743: void HandleEvents(void)
1.1       root      744: {
1.1.1.2 ! root      745:        XEvent event;
1.1       root      746:        int b;
1.1.1.2 ! root      747:        qboolean dowarp = false;
        !           748:        int mwx = vid.width/2;
        !           749:        int mwy = vid.height/2;
1.1       root      750:    
1.1.1.2 ! root      751:        while (XPending(dpy)) {
1.1       root      752: 
1.1.1.2 ! root      753:                XNextEvent(dpy, &event);
1.1       root      754: 
1.1.1.2 ! root      755:                switch(event.type) {
        !           756:                case KeyPress:
        !           757:                case KeyRelease:
        !           758:                        if (in_state && in_state->Key_Event_fp)
        !           759:                                in_state->Key_Event_fp (XLateKey(&event.xkey), event.type == KeyPress);
        !           760:                        break;
        !           761: 
        !           762:                case MotionNotify:
        !           763:                        if (ignorefirst) {
        !           764:                                ignorefirst = false;
        !           765:                                break;
        !           766:                        }
        !           767: 
        !           768:                        if (mouse_active) {
        !           769:                                if (dgamouse) {
        !           770:                                        mx += (event.xmotion.x + win_x) * 2;
        !           771:                                        my += (event.xmotion.y + win_y) * 2;
        !           772:                                } 
        !           773:                                else 
        !           774:                                {
        !           775:                                        mx += ((int)event.xmotion.x - mwx) * 2;
        !           776:                                        my += ((int)event.xmotion.y - mwy) * 2;
        !           777:                                        mwx = event.xmotion.x;
        !           778:                                        mwy = event.xmotion.y;
        !           779: 
        !           780:                                        if (mx || my)
        !           781:                                                dowarp = true;
        !           782:                                }
        !           783:                        }
        !           784:                        break;
        !           785: 
        !           786: 
        !           787:                        break;
        !           788: 
        !           789:                case ButtonPress:
        !           790:                        b=-1;
        !           791:                        if (event.xbutton.button == 1)
        !           792:                                b = 0;
        !           793:                        else if (event.xbutton.button == 2)
        !           794:                                b = 2;
        !           795:                        else if (event.xbutton.button == 3)
        !           796:                                b = 1;
        !           797:                        if (b>=0)
        !           798:                                mouse_buttonstate |= 1<<b;
        !           799:                        break;
        !           800: 
        !           801:                case ButtonRelease:
        !           802:                        b=-1;
        !           803:                        if (event.xbutton.button == 1)
        !           804:                                b = 0;
        !           805:                        else if (event.xbutton.button == 2)
        !           806:                                b = 2;
        !           807:                        else if (event.xbutton.button == 3)
        !           808:                                b = 1;
        !           809:                        if (b>=0)
        !           810:                                mouse_buttonstate &= ~(1<<b);
        !           811:                        break;
        !           812:                
        !           813:                case CreateNotify :
        !           814:                        ri.Cvar_Set( "vid_xpos", va("%d", event.xcreatewindow.x));
        !           815:                        ri.Cvar_Set( "vid_ypos", va("%d", event.xcreatewindow.y));
        !           816:                        vid_xpos->modified = false;
        !           817:                        vid_ypos->modified = false;
        !           818:                        win_x = event.xcreatewindow.x;
        !           819:                        win_y = event.xcreatewindow.y;
        !           820:                        break;
        !           821: 
        !           822:                case ConfigureNotify :
        !           823:                        ri.Cvar_Set( "vid_xpos", va("%d", event.xcreatewindow.x));
        !           824:                        ri.Cvar_Set( "vid_ypos", va("%d", event.xcreatewindow.y));
        !           825:                        vid_xpos->modified = false;
        !           826:                        vid_ypos->modified = false;
        !           827:                        win_x = event.xconfigure.x;
        !           828:                        win_y = event.xconfigure.y;
        !           829:                        config_notify_width = event.xconfigure.width;
        !           830:                        config_notify_height = event.xconfigure.height;
        !           831:                        if (config_notify_width != vid.width ||
        !           832:                                config_notify_height != vid.height)
        !           833:                                XMoveResizeWindow(dpy, win, win_x, win_y, vid.width, vid.height);
        !           834:                        config_notify = 1;
        !           835:                        break;
        !           836: 
        !           837:                default:
        !           838:                        if (doShm && event.type == x_shmeventtype)
        !           839:                                oktodraw = true;
        !           840:                        if (event.type == Expose && !event.xexpose.count)
        !           841:                                exposureflag = true;
1.1       root      842:                }
                    843:        }
1.1.1.2 ! root      844:           
        !           845:        if (dowarp) {
        !           846:                /* move the mouse to the window center again */
        !           847:                XWarpPointer(dpy,None,win,0,0,0,0, vid.width/2,vid.height/2);
        !           848:        }
1.1       root      849: }
                    850: 
                    851: /*****************************************************************************/
                    852: 
                    853: /*
                    854: ** SWimp_Init
                    855: **
                    856: ** This routine is responsible for initializing the implementation
                    857: ** specific stuff in a software rendering subsystem.
                    858: */
                    859: int SWimp_Init( void *hInstance, void *wndProc )
                    860: {
1.1.1.2 ! root      861: 
        !           862:        vid_xpos = ri.Cvar_Get ("vid_xpos", "3", CVAR_ARCHIVE);
        !           863:        vid_ypos = ri.Cvar_Get ("vid_ypos", "22", CVAR_ARCHIVE);
        !           864: 
1.1       root      865: // open the display
1.1.1.2 ! root      866:        dpy = XOpenDisplay(0);
        !           867:        if (!dpy)
1.1       root      868:        {
                    869:                if (getenv("DISPLAY"))
                    870:                        Sys_Error("VID: Could not open display [%s]\n",
                    871:                                getenv("DISPLAY"));
                    872:                else
                    873:                        Sys_Error("VID: Could not open local display\n");
                    874:        }
                    875: 
                    876: // catch signals so i can turn on auto-repeat
                    877: 
                    878:        {
                    879:                struct sigaction sa;
                    880:                sigaction(SIGINT, 0, &sa);
                    881:                sa.sa_handler = TragicDeath;
                    882:                sigaction(SIGINT, &sa, 0);
                    883:                sigaction(SIGTERM, &sa, 0);
                    884:        }
                    885: 
                    886:        return true;
                    887: }
                    888: 
                    889: /*
                    890: ** SWimp_InitGraphics
                    891: **
                    892: ** This initializes the software refresh's implementation specific
                    893: ** graphics subsystem.  In the case of Windows it creates DIB or
                    894: ** DDRAW surfaces.
                    895: **
                    896: ** The necessary width and height parameters are grabbed from
                    897: ** vid.width and vid.height.
                    898: */
                    899: static qboolean SWimp_InitGraphics( qboolean fullscreen )
                    900: {
                    901:        int pnum, i;
                    902:        XVisualInfo template;
                    903:        int num_visuals;
                    904:        int template_mask;
1.1.1.2 ! root      905:        Window root;
1.1       root      906: 
                    907:        srandom(getpid());
                    908: 
                    909:        // free resources in use
                    910:        SWimp_Shutdown ();
                    911: 
                    912:        // let the sound and input subsystems know about the new window
                    913:        ri.Vid_NewWindow (vid.width, vid.height);
                    914: 
1.1.1.2 ! root      915: //     XAutoRepeatOff(dpy);
1.1       root      916: 
                    917: // for debugging only
1.1.1.2 ! root      918:        XSynchronize(dpy, True);
1.1       root      919: 
                    920: // check for command-line window size
                    921:        template_mask = 0;
                    922: 
                    923: #if 0
                    924: // specify a visual id
                    925:        if ((pnum=COM_CheckParm("-visualid")))
                    926:        {
                    927:                if (pnum >= com_argc-1)
                    928:                        Sys_Error("VID: -visualid <id#>\n");
                    929:                template.visualid = Q_atoi(com_argv[pnum+1]);
                    930:                template_mask = VisualIDMask;
                    931:        }
                    932: 
                    933: // If not specified, use default visual
                    934:        else
                    935: #endif
                    936:        {
                    937:                int screen;
1.1.1.2 ! root      938:                screen = XDefaultScreen(dpy);
1.1       root      939:                template.visualid =
1.1.1.2 ! root      940:                        XVisualIDFromVisual(XDefaultVisual(dpy, screen));
1.1       root      941:                template_mask = VisualIDMask;
                    942:        }
                    943: 
                    944: // pick a visual- warn if more than one was available
1.1.1.2 ! root      945:        x_visinfo = XGetVisualInfo(dpy, template_mask, &template, &num_visuals);
1.1       root      946:        if (num_visuals > 1)
                    947:        {
                    948:                printf("Found more than one visual id at depth %d:\n", template.depth);
                    949:                for (i=0 ; i<num_visuals ; i++)
                    950:                        printf("        -visualid %d\n", (int)(x_visinfo[i].visualid));
                    951:        }
                    952:        else if (num_visuals == 0)
                    953:        {
                    954:                if (template_mask == VisualIDMask)
                    955:                        Sys_Error("VID: Bad visual id %d\n", template.visualid);
                    956:                else
                    957:                        Sys_Error("VID: No visuals at depth %d\n", template.depth);
                    958:        }
                    959: 
                    960: #if 0
1.1.1.2 ! root      961:        printf("Using visualid %d:\n", (int)(x_visinfo->visualid));
        !           962:        printf("        screen %d\n", x_visinfo->screen);
        !           963:        printf("        red_mask 0x%x\n", (int)(x_visinfo->red_mask));
        !           964:        printf("        green_mask 0x%x\n", (int)(x_visinfo->green_mask));
        !           965:        printf("        blue_mask 0x%x\n", (int)(x_visinfo->blue_mask));
        !           966:        printf("        colormap_size %d\n", x_visinfo->colormap_size);
        !           967:        printf("        bits_per_rgb %d\n", x_visinfo->bits_per_rgb);
1.1       root      968: #endif
                    969: 
                    970:        x_vis = x_visinfo->visual;
1.1.1.2 ! root      971:        root = XRootWindow(dpy, x_visinfo->screen);
1.1       root      972: 
                    973: // setup attributes for main window
                    974:        {
                    975:           int attribmask = CWEventMask  | CWColormap | CWBorderPixel;
                    976:           XSetWindowAttributes attribs;
                    977:           Colormap tmpcmap;
                    978:           
1.1.1.2 ! root      979:           tmpcmap = XCreateColormap(dpy, root, x_vis, AllocNone);
1.1       root      980:           
1.1.1.2 ! root      981:           attribs.event_mask = X_MASK;
1.1       root      982:           attribs.border_pixel = 0;
                    983:           attribs.colormap = tmpcmap;
                    984: 
                    985: // create the main window
1.1.1.2 ! root      986:                win = XCreateWindow(dpy, root, (int)vid_xpos->value, (int)vid_ypos->value, 
        !           987:                        vid.width, vid.height, 0, x_visinfo->depth, InputOutput, x_vis, 
        !           988:                        attribmask, &attribs );
        !           989:                XStoreName(dpy, win, "Quake II");
1.1       root      990: 
                    991:                if (x_visinfo->class != TrueColor)
1.1.1.2 ! root      992:                        XFreeColormap(dpy, tmpcmap);
1.1       root      993:        }
                    994: 
                    995:        if (x_visinfo->depth == 8)
                    996:        {
                    997:        // create and upload the palette
                    998:                if (x_visinfo->class == PseudoColor)
                    999:                {
1.1.1.2 ! root     1000:                        x_cmap = XCreateColormap(dpy, win, x_vis, AllocAll);
        !          1001:                        XSetWindowColormap(dpy, win, x_cmap);
1.1       root     1002:                }
                   1003: 
                   1004:        }
                   1005: 
                   1006: // create the GC
                   1007:        {
                   1008:                XGCValues xgcvalues;
                   1009:                int valuemask = GCGraphicsExposures;
                   1010:                xgcvalues.graphics_exposures = False;
1.1.1.2 ! root     1011:                x_gc = XCreateGC(dpy, win, valuemask, &xgcvalues );
1.1       root     1012:        }
                   1013: 
1.1.1.2 ! root     1014:        XMapWindow(dpy, win);
        !          1015:        XMoveWindow(dpy, win, (int)vid_xpos->value, (int)vid_ypos->value);
1.1       root     1016: 
                   1017: // wait for first exposure event
                   1018:        {
                   1019:                XEvent event;
1.1.1.2 ! root     1020:                exposureflag = false;
1.1       root     1021:                do
                   1022:                {
1.1.1.2 ! root     1023:                        HandleEvents();
        !          1024:                } while (!exposureflag);
1.1       root     1025:        }
                   1026: // now safe to draw
                   1027: 
                   1028: // even if MITSHM is available, make sure it's a local connection
1.1.1.2 ! root     1029:        if (XShmQueryExtension(dpy))
1.1       root     1030:        {
                   1031:                char *displayname;
                   1032:                doShm = true;
                   1033:                displayname = (char *) getenv("DISPLAY");
                   1034:                if (displayname)
                   1035:                {
                   1036:                        char *d = displayname;
                   1037:                        while (*d && (*d != ':')) d++;
                   1038:                        if (*d) *d = 0;
                   1039:                        if (!(!strcasecmp(displayname, "unix") || !*displayname))
                   1040:                                doShm = false;
                   1041:                }
                   1042:        }
                   1043: 
                   1044:        if (doShm)
                   1045:        {
1.1.1.2 ! root     1046:                x_shmeventtype = XShmGetEventBase(dpy) + ShmCompletion;
1.1       root     1047:                ResetSharedFrameBuffers();
                   1048:        }
                   1049:        else
                   1050:                ResetFrameBuffer();
                   1051: 
                   1052:        current_framebuffer = 0;
                   1053:        vid.rowbytes = x_framebuffer[0]->bytes_per_line;
                   1054:        vid.buffer = x_framebuffer[0]->data;
                   1055: 
1.1.1.2 ! root     1056: //     XSynchronize(dpy, False);
1.1       root     1057: 
                   1058:        X11_active = true;
                   1059: 
                   1060:        return true;
                   1061: }
                   1062: 
                   1063: /*
                   1064: ** SWimp_EndFrame
                   1065: **
                   1066: ** This does an implementation specific copy from the backbuffer to the
                   1067: ** front buffer.  In the Win32 case it uses BitBlt or BltFast depending
                   1068: ** on whether we're using DIB sections/GDI or DDRAW.
                   1069: */
                   1070: void SWimp_EndFrame (void)
                   1071: {
                   1072: // if the window changes dimension, skip this frame
                   1073: #if 0
                   1074:        if (config_notify)
                   1075:        {
                   1076:                fprintf(stderr, "config notify\n");
                   1077:                config_notify = 0;
                   1078:                vid.width = config_notify_width & ~7;
                   1079:                vid.height = config_notify_height;
                   1080:                if (doShm)
                   1081:                        ResetSharedFrameBuffers();
                   1082:                else
                   1083:                        ResetFrameBuffer();
                   1084:                vid.rowbytes = x_framebuffer[0]->bytes_per_line;
                   1085:                vid.buffer = x_framebuffer[current_framebuffer]->data;
                   1086:                vid.recalc_refdef = 1;                          // force a surface cache flush
                   1087:                Con_CheckResize();
                   1088:                Con_Clear_f();
                   1089:                return;
                   1090:        }
                   1091: #endif
                   1092: 
                   1093:        if (doShm)
                   1094:        {
1.1.1.2 ! root     1095:                if (x_visinfo->depth == 16)
        !          1096:                        st2_fixup( x_framebuffer[current_framebuffer], 0, 0, vid.width, vid.height);
        !          1097:                else if (x_visinfo->depth == 24)
        !          1098:                        st3_fixup( x_framebuffer[current_framebuffer], 0, 0, vid.width, vid.height);
        !          1099:                if (!XShmPutImage(dpy, win, x_gc,
        !          1100:                        x_framebuffer[current_framebuffer], 0, 0, 0, 0, vid.width, vid.height, True))
        !          1101:                        Sys_Error("VID_Update: XShmPutImage failed\n");
1.1       root     1102:                oktodraw = false;
                   1103:                while (!oktodraw) 
1.1.1.2 ! root     1104:                        HandleEvents();
1.1       root     1105:                current_framebuffer = !current_framebuffer;
                   1106:                vid.buffer = x_framebuffer[current_framebuffer]->data;
1.1.1.2 ! root     1107:                XSync(dpy, False);
1.1       root     1108:        }
                   1109:        else
                   1110:        {
1.1.1.2 ! root     1111:                if (x_visinfo->depth == 16)
        !          1112:                        st2_fixup( x_framebuffer[current_framebuffer], 0, 0, vid.width, vid.height);
        !          1113:                else if (x_visinfo->depth == 24)
        !          1114:                        st3_fixup( x_framebuffer[current_framebuffer], 0, 0, vid.width, vid.height);
        !          1115:                XPutImage(dpy, win, x_gc, x_framebuffer[0], 0, 0, 0, 0, vid.width, vid.height);
        !          1116:                XSync(dpy, False);
1.1       root     1117:        }
                   1118: }
                   1119: 
                   1120: /*
                   1121: ** SWimp_SetMode
                   1122: */
                   1123: rserr_t SWimp_SetMode( int *pwidth, int *pheight, int mode, qboolean fullscreen )
                   1124: {
                   1125:        rserr_t retval = rserr_ok;
                   1126: 
                   1127:        ri.Con_Printf (PRINT_ALL, "setting mode %d:", mode );
                   1128: 
                   1129:        if ( !ri.Vid_GetModeInfo( pwidth, pheight, mode ) )
                   1130:        {
                   1131:                ri.Con_Printf( PRINT_ALL, " invalid mode\n" );
                   1132:                return rserr_invalid_mode;
                   1133:        }
                   1134: 
                   1135:        ri.Con_Printf( PRINT_ALL, " %d %d\n", *pwidth, *pheight);
                   1136: 
                   1137:        if ( !SWimp_InitGraphics( false ) ) {
                   1138:                // failed to set a valid mode in windowed mode
                   1139:                return rserr_invalid_mode;
                   1140:        }
                   1141: 
                   1142:        R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table );
                   1143: 
                   1144:        return retval;
                   1145: }
                   1146: 
                   1147: /*
                   1148: ** SWimp_SetPalette
                   1149: **
                   1150: ** System specific palette setting routine.  A NULL palette means
                   1151: ** to use the existing palette.  The palette is expected to be in
                   1152: ** a padded 4-byte xRGB format.
                   1153: */
                   1154: void SWimp_SetPalette( const unsigned char *palette )
                   1155: {
                   1156:        int i;
                   1157:        XColor colors[256];
                   1158: 
                   1159:        if (!X11_active)
                   1160:                return;
                   1161: 
                   1162:     if ( !palette )
                   1163:         palette = ( const unsigned char * ) sw_state.currentpalette;
                   1164:  
1.1.1.2 ! root     1165:        for(i=0;i<256;i++) {
        !          1166:                st2d_8to16table[i]= xlib_rgb16(palette[i*4], palette[i*4+1],palette[i*4+2]);
        !          1167:                st2d_8to24table[i]= xlib_rgb24(palette[i*4], palette[i*4+1],palette[i*4+2]);
        !          1168:        }
1.1       root     1169: 
                   1170:        if (x_visinfo->class == PseudoColor && x_visinfo->depth == 8)
                   1171:        {
                   1172:                for (i=0 ; i<256 ; i++)
                   1173:                {
                   1174:                        colors[i].pixel = i;
                   1175:                        colors[i].flags = DoRed|DoGreen|DoBlue;
                   1176:                        colors[i].red = palette[i*4] * 257;
                   1177:                        colors[i].green = palette[i*4+1] * 257;
                   1178:                        colors[i].blue = palette[i*4+2] * 257;
                   1179:                }
1.1.1.2 ! root     1180:                XStoreColors(dpy, x_cmap, colors, 256);
1.1       root     1181:        }
                   1182: }
                   1183: 
                   1184: /*
                   1185: ** SWimp_Shutdown
                   1186: **
                   1187: ** System specific graphics subsystem shutdown routine.  Destroys
                   1188: ** DIBs or DDRAW surfaces as appropriate.
                   1189: */
                   1190: void SWimp_Shutdown( void )
                   1191: {
                   1192:        int i;
                   1193: 
                   1194:        if (!X11_active)
                   1195:                return;
                   1196: 
                   1197:        if (doShm) {
                   1198:                for (i = 0; i < 2; i++)
                   1199:                        if (x_framebuffer[i]) {
1.1.1.2 ! root     1200:                                XShmDetach(dpy, &x_shminfo[i]);
1.1       root     1201:                                free(x_framebuffer[i]);
                   1202:                                shmdt(x_shminfo[i].shmaddr);
                   1203:                                x_framebuffer[i] = NULL;
                   1204:                        }
                   1205:        } else if (x_framebuffer[0]) {
                   1206:                free(x_framebuffer[0]->data);
                   1207:                free(x_framebuffer[0]);
                   1208:                x_framebuffer[0] = NULL;
                   1209:        }
                   1210: 
1.1.1.2 ! root     1211:        XDestroyWindow( dpy, win );
1.1       root     1212: 
1.1.1.2 ! root     1213: //     XAutoRepeatOn(dpy);
        !          1214: //     XCloseDisplay(dpy);
1.1       root     1215: 
                   1216:        X11_active = false;
                   1217: }
                   1218: 
                   1219: /*
                   1220: ** SWimp_AppActivate
                   1221: */
                   1222: void SWimp_AppActivate( qboolean active )
                   1223: {
                   1224: }
                   1225: 
                   1226: //===============================================================================
                   1227: 
                   1228: /*
                   1229: ================
                   1230: Sys_MakeCodeWriteable
                   1231: ================
                   1232: */
                   1233: void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length)
                   1234: {
                   1235: 
                   1236:        int r;
                   1237:        unsigned long addr;
                   1238:        int psize = getpagesize();
                   1239: 
                   1240:        addr = (startaddr & ~(psize-1)) - psize;
                   1241: 
                   1242: //     fprintf(stderr, "writable code %lx(%lx)-%lx, length=%lx\n", startaddr,
                   1243: //                     addr, startaddr+length, length);
                   1244: 
                   1245:        r = mprotect((char*)addr, length + startaddr - addr + psize, 7);
                   1246: 
                   1247:        if (r < 0)
                   1248:                Sys_Error("Protection change failed\n");
                   1249: 
                   1250: }
                   1251: 
                   1252: /*****************************************************************************/
                   1253: /* KEYBOARD                                                                  */
                   1254: /*****************************************************************************/
                   1255: 
                   1256: Key_Event_fp_t Key_Event_fp;
                   1257: 
                   1258: void KBD_Init(Key_Event_fp_t fp)
                   1259: {
                   1260:        Key_Event_fp = fp;
                   1261: }
                   1262: 
                   1263: void KBD_Update(void)
                   1264: {
                   1265: // get events from x server
1.1.1.2 ! root     1266:        HandleEvents();
1.1       root     1267: }
                   1268: 
                   1269: void KBD_Close(void)
                   1270: {
                   1271: }
                   1272: 
                   1273: 

unix.superglobalmegacorp.com

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