X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=vid_glx.c;h=01d2486be4d5a0e09d1aa764b2aab474179f31f5;hb=6357d9b84d415b95c7711f67a7a8311d693ba2ee;hp=395bb605e6c8a96db3a5753b06b7cb62da12e2a0;hpb=b409100fe17b5496698d36cdda609dd50f366d53;p=xonotic%2Fdarkplaces.git diff --git a/vid_glx.c b/vid_glx.c index 395bb605..01d2486b 100644 --- a/vid_glx.c +++ b/vid_glx.c @@ -39,6 +39,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #endif #include +// get the Uchar type +#include "utf8lib.h" + #include "nexuiz.xpm" #include "darkplaces.xpm" @@ -122,16 +125,57 @@ static Visual *vidx11_visual; static Colormap vidx11_colormap; /*-----------------------------------------------------------------------*/ +// -static int XLateKey(XKeyEvent *ev, char *ascii) +long keysym2ucs(KeySym keysym); +void DP_Xutf8LookupString(XKeyEvent * ev, + Uchar *uch, + KeySym * keysym_return, + Status * status_return) +{ + int rc; + KeySym keysym; + int codepoint; + char buffer[64]; + int nbytes = sizeof(buffer); + + rc = XLookupString(ev, buffer, nbytes, &keysym, NULL); + + if (rc > 0) { + codepoint = buffer[0] & 0xFF; + } else { + codepoint = keysym2ucs(keysym); + } + + if (codepoint < 0) { + if (keysym == None) { + *status_return = XLookupNone; + } else { + *status_return = XLookupKeySym; + *keysym_return = keysym; + } + *uch = 0; + return; + } + + *uch = codepoint; + + if (keysym != None) { + *keysym_return = keysym; + *status_return = XLookupBoth; + } else { + *status_return = XLookupChars; + } +} +static int XLateKey(XKeyEvent *ev, Uchar *ascii) { int key = 0; - char buf[64]; + //char buf[64]; KeySym keysym, shifted; + Status status; keysym = XLookupKeysym (ev, 0); - XLookupString(ev, buf, sizeof buf, &shifted, 0); - *ascii = buf[0]; + DP_Xutf8LookupString(ev, ascii, &shifted, &status); switch(keysym) { @@ -398,7 +442,7 @@ static void HandleEvents(void) { XEvent event; int key; - char ascii; + Uchar unicode; qboolean dowarp = false; if (!vidx11_display) @@ -412,14 +456,14 @@ static void HandleEvents(void) { case KeyPress: // key pressed - key = XLateKey (&event.xkey, &ascii); - Key_Event(key, ascii, true); + key = XLateKey (&event.xkey, &unicode); + Key_Event(key, unicode, true); break; case KeyRelease: // key released - key = XLateKey (&event.xkey, &ascii); - Key_Event(key, ascii, false); + key = XLateKey (&event.xkey, &unicode); + Key_Event(key, unicode, false); break; case MotionNotify: @@ -475,10 +519,14 @@ static void HandleEvents(void) // window changed size/location win_x = event.xconfigure.x; win_y = event.xconfigure.y; - if(vid_resizable.integer < 2) + if(vid_resizable.integer < 2 || vid_isnetwmfullscreen) { vid.width = event.xconfigure.width; vid.height = event.xconfigure.height; + if(vid_isnetwmfullscreen) + Con_Printf("NetWM fullscreen: actually using resolution %dx%d\n", vid.width, vid.height); + else + Con_DPrintf("Updating to ConfigureNotify resolution %dx%d\n", vid.width, vid.height); } break; case DestroyNotify: @@ -685,18 +733,18 @@ void InitSig(void) void VID_Finish (void) { - vid_usevsync = vid_vsync.integer && !cls.timedemo && gl_videosyncavailable; - if (vid_usingvsync != vid_usevsync && gl_videosyncavailable) + vid_usevsync = vid_vsync.integer && !cls.timedemo && qglXSwapIntervalSGI; + if (vid_usingvsync != vid_usevsync) { vid_usingvsync = vid_usevsync; if (qglXSwapIntervalSGI (vid_usevsync)) Con_Print("glXSwapIntervalSGI didn't accept the vid_vsync change, it will take effect on next vid_restart (GLX_SGI_swap_control does not allow turning off vsync)\n"); } - if (r_render.integer) + if (!vid_hidden) { CHECKGLERROR - if (r_speeds.integer || gl_finish.integer) + if (r_speeds.integer == 2 || gl_finish.integer) { qglFinish();CHECKGLERROR } @@ -755,7 +803,7 @@ void VID_BuildGLXAttrib(int *attrib, qboolean stencil, qboolean stereobuffer, in *attrib++ = None; } -int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate, int stereobuffer, int samples) +qboolean VID_InitMode(viddef_mode_t *mode) { int i; int attrib[32]; @@ -830,7 +878,7 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate return false; } - VID_BuildGLXAttrib(attrib, bpp == 32, stereobuffer, samples); + VID_BuildGLXAttrib(attrib, mode->bitsperpixel == 32, mode->stereobuffer, mode->samples); visinfo = qglXChooseVisual(vidx11_display, vidx11_screen, attrib); if (!visinfo) { @@ -838,7 +886,7 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate return false; } - if (fullscreen) + if (mode->fullscreen) { if(vid_netwmfullscreen.integer) { @@ -846,6 +894,7 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate vid_isnetwmfullscreen = true; vid_isfullscreen = true; // width and height will be filled in later + Con_DPrintf("Using NetWM fullscreen mode\n"); } if(!vid_isfullscreen && vidmode_ext) @@ -867,11 +916,11 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate for (i = 0; i < num_vidmodes; i++) { - if (width > vidmodes[i]->hdisplay || height > vidmodes[i]->vdisplay) + if (mode->width > vidmodes[i]->hdisplay || mode->height > vidmodes[i]->vdisplay) continue; - x = width - vidmodes[i]->hdisplay; - y = height - vidmodes[i]->vdisplay; + x = mode->width - vidmodes[i]->hdisplay; + y = mode->height - vidmodes[i]->vdisplay; dist = (x * x) + (y * y); if (best_fit == -1 || dist < best_dist) { @@ -885,8 +934,8 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate // LordHavoc: changed from ActualWidth/ActualHeight =, // to width/height =, so the window will take the full area of // the mode chosen - width = vidmodes[best_fit]->hdisplay; - height = vidmodes[best_fit]->vdisplay; + mode->width = vidmodes[best_fit]->hdisplay; + mode->height = vidmodes[best_fit]->vdisplay; // change to the mode XF86VidModeSwitchToMode(vidx11_display, vidx11_screen, vidmodes[best_fit]); @@ -896,6 +945,7 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate // Move the viewport to top left XF86VidModeSetViewPort(vidx11_display, vidx11_screen, 0, 0); + Con_DPrintf("Using XVidMode fullscreen mode at %dx%d\n", mode->width, mode->height); } free(vidmodes); @@ -907,8 +957,9 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate // use the full desktop resolution vid_isfullscreen = true; // width and height will be filled in later - width = DisplayWidth(vidx11_display, vidx11_screen); - height = DisplayHeight(vidx11_display, vidx11_screen); + mode->width = DisplayWidth(vidx11_display, vidx11_screen); + mode->height = DisplayHeight(vidx11_display, vidx11_screen); + Con_DPrintf("Using X11 fullscreen mode at %dx%d\n", mode->width, mode->height); } } @@ -922,7 +973,7 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate vidx11_colormap = attr.colormap = XCreateColormap(vidx11_display, root, visinfo->visual, AllocNone); attr.event_mask = X_MASK; - if (fullscreen) + if (mode->fullscreen) { if(vid_isnetwmfullscreen) { @@ -944,7 +995,7 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; } - win = XCreateWindow(vidx11_display, root, 0, 0, width, height, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr); + win = XCreateWindow(vidx11_display, root, 0, 0, mode->width, mode->height, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr); wmhints = XAllocWMHints(); if(XpmCreatePixmapFromData(vidx11_display, win, @@ -959,12 +1010,15 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate szhints = XAllocSizeHints(); if(vid_resizable.integer == 0 && !vid_isnetwmfullscreen) { - szhints->min_width = szhints->max_width = width; - szhints->min_height = szhints->max_height = height; + szhints->min_width = szhints->max_width = mode->width; + szhints->min_height = szhints->max_height = mode->height; szhints->flags |= PMinSize | PMaxSize; } XmbSetWMProperties(vidx11_display, win, gamename, gamename, (char **) com_argv, com_argc, szhints, wmhints, clshints); + // strdup() allocates using malloc(), should be freed with free() + free(clshints->res_name); + free(clshints->res_class); XFree(clshints); XFree(wmhints); XFree(szhints); @@ -991,6 +1045,7 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate //XSync(vidx11_display, False); ctx = qglXCreateContext(vidx11_display, visinfo, NULL, True); + XFree(visinfo); // glXChooseVisual man page says to use XFree to free visinfo if (!ctx) { Con_Printf ("glXCreateContext failed\n"); @@ -1015,8 +1070,6 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate gl_platform = "GLX"; gl_platformextensions = qglXQueryExtensionsString(vidx11_display, vidx11_screen); - gl_videosyncavailable = false; - // COMMANDLINEOPTION: Linux GLX: -nogetprocaddress disables GLX_ARB_get_proc_address (not required, more formal method of getting extension functions) // COMMANDLINEOPTION: BSD GLX: -nogetprocaddress disables GLX_ARB_get_proc_address (not required, more formal method of getting extension functions) // COMMANDLINEOPTION: MacOSX GLX: -nogetprocaddress disables GLX_ARB_get_proc_address (not required, more formal method of getting extension functions) @@ -1024,7 +1077,7 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate // COMMANDLINEOPTION: Linux GLX: -novideosync disables GLX_SGI_swap_control // COMMANDLINEOPTION: BSD GLX: -novideosync disables GLX_SGI_swap_control // COMMANDLINEOPTION: MacOSX GLX: -novideosync disables GLX_SGI_swap_control - gl_videosyncavailable = GL_CheckExtension("GLX_SGI_swap_control", swapcontrolfuncs, "-novideosync", false); + GL_CheckExtension("GLX_SGI_swap_control", swapcontrolfuncs, "-novideosync", false); vid_usingmousegrab = false; vid_usingmouse = false; @@ -1038,6 +1091,7 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate if (!vid_x11_dgasupported) Con_Print( "Failed to detect XF86DGA Mouse extension\n" ); #endif + GL_Init(); return true; } @@ -1047,7 +1101,7 @@ void Sys_SendKeyEvents(void) static qboolean sound_active = true; // enable/disable sound on focus gain/loss - if (!vid_hidden && (vid_activewindow || !snd_mutewhenidle.integer)) + if ((!vid_hidden && vid_activewindow) || !snd_mutewhenidle.integer) { if (!sound_active) { @@ -1070,3 +1124,42 @@ void Sys_SendKeyEvents(void) void IN_Move (void) { } + +size_t VID_ListModes(vid_mode_t *modes, size_t maxcount) +{ + if(vidmode_ext) + { + int i, bpp; + size_t k; + XF86VidModeModeInfo **vidmodes; + int num_vidmodes; + + XF86VidModeGetAllModeLines(vidx11_display, vidx11_screen, &num_vidmodes, &vidmodes); + k = 0; + for (i = 0; i < num_vidmodes; i++) + { + if(k >= maxcount) + break; + // we don't get bpp info, so let's just assume all of 8, 15, 16, 24, 32 work + for(bpp = 8; bpp <= 32; bpp = ((bpp == 8) ? 15 : (bpp & 0xF8) + 8)) + { + if(k >= maxcount) + break; + modes[k].width = vidmodes[i]->hdisplay; + modes[k].height = vidmodes[i]->vdisplay; + modes[k].bpp = 8; + if(vidmodes[i]->dotclock && vidmodes[i]->htotal && vidmodes[i]->vtotal) + modes[k].refreshrate = vidmodes[i]->dotclock / vidmodes[i]->htotal / vidmodes[i]->vtotal; + else + modes[k].refreshrate = 60; + modes[k].pixelheight_num = 1; + modes[k].pixelheight_denom = 1; // xvidmode does not provide this + ++k; + } + } + // manpage of XF86VidModeGetAllModeLines says it should be freed by the caller + XFree(vidmodes); + return k; + } + return 0; // FIXME implement this +}