static int vid_mode_available (void) { #ifdef USE_VIDMODE_EXTENSION int MajorVersion, MinorVersion; int EventBase, ErrorBase; if (! dgaavail) return 0; if (! XF86VidModeQueryVersion (display, &MajorVersion, &MinorVersion)) { write_log ("Unable to query video extension version\n"); return 0; } if (! XF86VidModeQueryExtension (display, &EventBase, &ErrorBase)) { write_log ("Unable to query video extension information\n"); return 0; } if (MajorVersion < VidMode_MINMAJOR || (MajorVersion == VidMode_MINMAJOR && MinorVersion < VidMode_MINMINOR)) { /* Fail if the extension version in the server is too old */ write_log ("Xserver is running an old XFree86-VidMode version (%d.%d)\n", MajorVersion, MinorVersion); write_log ("Minimum required version is %d.%d\n", VidMode_MINMAJOR, VidMode_MINMINOR); return 0; } if (! get_vidmodes ()) { write_log ("Error getting video mode information\n"); return 0; } return 1; #else return 0; #endif }
GHOST_TSuccess GHOST_DisplayManagerX11:: getNumDisplaySettings( GHOST_TUns8 display, GHOST_TInt32& numSettings) const { #ifdef WITH_X11_XF86VMODE int majorVersion, minorVersion; XF86VidModeModeInfo **vidmodes; Display *dpy = m_system->getXDisplay(); GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); if (dpy == NULL) return GHOST_kFailure; majorVersion = minorVersion = 0; if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) { fprintf(stderr, "Error: XF86VidMode extension missing!\n"); return GHOST_kFailure; } if (XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes)) { XFree(vidmodes); } #else /* We only have one X11 setting at the moment. */ GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); numSettings = 1; #endif return GHOST_kSuccess; }
void X11DRV_XF86VM_Init(void) { Bool ok; int nmodes; unsigned int i; if (xf86vm_major) return; /* already initialized? */ /* see if XVidMode is available */ wine_tsx11_lock(); ok = XF86VidModeQueryExtension(gdi_display, &xf86vm_event, &xf86vm_error); if (ok) { X11DRV_expect_error(gdi_display, XVidModeErrorHandler, NULL); ok = XF86VidModeQueryVersion(gdi_display, &xf86vm_major, &xf86vm_minor); if (X11DRV_check_error()) ok = FALSE; } if (ok) { #ifdef X_XF86VidModeSetGammaRamp if (xf86vm_major > 2 || (xf86vm_major == 2 && xf86vm_minor >= 1)) { XF86VidModeGetGammaRampSize(gdi_display, DefaultScreen(gdi_display), &xf86vm_gammaramp_size); if (xf86vm_gammaramp_size == 256) xf86vm_use_gammaramp = TRUE; } #endif /* X_XF86VidModeSetGammaRamp */ /* retrieve modes */ if (usexvidmode && root_window == DefaultRootWindow( gdi_display )) ok = XF86VidModeGetAllModeLines(gdi_display, DefaultScreen(gdi_display), &nmodes, &real_xf86vm_modes); else ok = FALSE; /* In desktop mode, do not switch resolution... But still use the Gamma ramp stuff */ } wine_tsx11_unlock(); if (!ok) return; TRACE("XVidMode modes: count=%d\n", nmodes); real_xf86vm_mode_count = nmodes; dd_modes = X11DRV_Settings_SetHandlers("XF86VidMode", X11DRV_XF86VM_GetCurrentMode, X11DRV_XF86VM_SetCurrentMode, nmodes, 1); /* convert modes to DDHALMODEINFO format */ for (i=0; i<real_xf86vm_mode_count; i++) { convert_modeinfo(real_xf86vm_modes[i]); } /* add modes for different color depths */ X11DRV_Settings_AddDepthModes(); dd_mode_count = X11DRV_Settings_GetModeCount(); TRACE("Available DD modes: count=%d\n", dd_mode_count); TRACE("Enabling XVidMode\n"); }
int vidmode_start(vidmode_state_t *state) { int r; int screen_num = state->screen_num; if (screen_num < 0) screen_num = DefaultScreen(state->display); state->screen_num = screen_num; /* Query extension version */ int major, minor; r = XF86VidModeQueryVersion(state->display, &major, &minor); if (!r) { fprintf(stderr, _("X request failed: %s\n"), "XF86VidModeQueryVersion"); return -1; } /* Request size of gamma ramps */ r = XF86VidModeGetGammaRampSize(state->display, state->screen_num, &state->ramp_size); if (!r) { fprintf(stderr, _("X request failed: %s\n"), "XF86VidModeGetGammaRampSize"); return -1; } if (state->ramp_size == 0) { fprintf(stderr, _("Gamma ramp size too small: %i\n"), state->ramp_size); return -1; } /* Allocate space for saved gamma ramps */ state->saved_ramps = malloc(3*state->ramp_size*sizeof(uint16_t)); if (state->saved_ramps == NULL) { perror("malloc"); return -1; } uint16_t *gamma_r = &state->saved_ramps[0*state->ramp_size]; uint16_t *gamma_g = &state->saved_ramps[1*state->ramp_size]; uint16_t *gamma_b = &state->saved_ramps[2*state->ramp_size]; /* Save current gamma ramps so we can restore them at program exit. */ r = XF86VidModeGetGammaRamp(state->display, state->screen_num, state->ramp_size, gamma_r, gamma_g, gamma_b); if (!r) { fprintf(stderr, _("X request failed: %s\n"), "XF86VidModeGetGammaRamp"); return -1; } return 0; }
GHOST_TSuccess GHOST_DisplayManagerX11:: getDisplaySetting( GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const { Display *dpy = m_system->getXDisplay(); if (dpy == NULL) return GHOST_kFailure; (void)display; #ifdef WITH_X11_XF86VMODE int majorVersion, minorVersion; GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); majorVersion = minorVersion = 0; if (XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) { XF86VidModeModeInfo **vidmodes; int numSettings; if (XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes)) { GHOST_ASSERT(index < numSettings, "Requested setting outside of valid range.\n"); setting.xPixels = vidmodes[index]->hdisplay; setting.yPixels = vidmodes[index]->vdisplay; setting.bpp = DefaultDepth(dpy, DefaultScreen(dpy)); setting.frequency = calculate_rate(vidmodes[index]); XFree(vidmodes); return GHOST_kSuccess; } } else { fprintf(stderr, "Warning: XF86VidMode extension missing!\n"); /* fallback to non xf86vmode below */ } #endif /* WITH_X11_XF86VMODE */ GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); GHOST_ASSERT(index < 1, "Requested setting outside of valid range.\n"); (void)index; setting.xPixels = DisplayWidth(dpy, DefaultScreen(dpy)); setting.yPixels = DisplayHeight(dpy, DefaultScreen(dpy)); setting.bpp = DefaultDepth(dpy, DefaultScreen(dpy)); setting.frequency = 60.0f; return GHOST_kSuccess; }
int main (int argc, char **argv) { GError *error = NULL; int op, event, err; #ifdef ENABLE_NLS bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); # ifdef HAVE_BIND_TEXTDOMAIN_CODESET bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); # endif textdomain (GETTEXT_PACKAGE); #endif if (error) { fprintf (stderr, "%s\n", error->message); exit (1); } if (! gtk_init_with_args (&argc, &argv, NULL, NULL, NULL, &error)) { fprintf (stderr, "%s", error->message); g_error_free (error); exit (1); } if (! XQueryExtension (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), XF86_VIDMODE_NAME, &op, &event, &err)) { g_message ("no " XF86_VIDMODE_NAME " extension"); } else { # ifdef HAVE_XF86VMODE_GAMMA int major; int minor; if (! XF86VidModeQueryVersion (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &major, &minor)) { g_message ("unable to get " XF86_VIDMODE_NAME " version"); } else { g_message (XF86_VIDMODE_NAME " version %d.%d", major, minor); } # else /* !HAVE_XF86VMODE_GAMMA */ g_message ("no support for display's " XF86_VIDMODE_NAME " extension"); # endif /* !HAVE_XF86VMODE_GAMMA */ } gs_debug_init (TRUE, FALSE); test_fade (); gs_debug_shutdown (); return 0; }
/* FIXME: bits is currently unused */ Bool createGLWindow(char* title, int width, int height, int bits, Bool fullscreenflag) { XVisualInfo *vi; Colormap cmap; int dpyWidth, dpyHeight; int i; int glxMajorVersion, glxMinorVersion; int vidModeMajorVersion, vidModeMinorVersion; XF86VidModeModeInfo **modes; int modeNum; int bestMode; Atom wmDelete; Window winDummy; unsigned int borderDummy; GLWin.fs = fullscreenflag; /* set best mode to current */ bestMode = 0; /* get a connection */ GLWin.dpy = XOpenDisplay(0); GLWin.screen = DefaultScreen(GLWin.dpy); XF86VidModeQueryVersion(GLWin.dpy, &vidModeMajorVersion, &vidModeMinorVersion); printf("XF86VidModeExtension-Version %d.%d\n", vidModeMajorVersion, vidModeMinorVersion); XF86VidModeGetAllModeLines(GLWin.dpy, GLWin.screen, &modeNum, &modes); /* save desktop-resolution before switching modes */ GLWin.deskMode = *modes[0]; /* look for mode with requested resolution */ for (i = 0; i < modeNum; i++) { if ((modes[i]->hdisplay == width) && (modes[i]->vdisplay == height)) { bestMode = i; } } /* get an appropriate visual */ vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListDbl); if (vi == NULL) { vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListSgl); printf("Only Singlebuffered Visual!\n"); } else { printf("Got Doublebuffered Visual!\n"); } glXQueryVersion(GLWin.dpy, &glxMajorVersion, &glxMinorVersion); printf("glX-Version %d.%d\n", glxMajorVersion, glxMinorVersion); /* create a GLX context */ GLWin.ctx = glXCreateContext(GLWin.dpy, vi, 0, GL_TRUE); /* create a color map */ cmap = XCreateColormap(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen), vi->visual, AllocNone); GLWin.attr.colormap = cmap; GLWin.attr.border_pixel = 0; if (GLWin.fs) { XF86VidModeSwitchToMode(GLWin.dpy, GLWin.screen, modes[bestMode]); XF86VidModeSetViewPort(GLWin.dpy, GLWin.screen, 0, 0); dpyWidth = modes[bestMode]->hdisplay; dpyHeight = modes[bestMode]->vdisplay; printf("Resolution %dx%d\n", dpyWidth, dpyHeight); XFree(modes); /* create a fullscreen window */ GLWin.attr.override_redirect = True; GLWin.attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask; GLWin.win = XCreateWindow(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen), 0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &GLWin.attr); XWarpPointer(GLWin.dpy, None, GLWin.win, 0, 0, 0, 0, 0, 0); XMapRaised(GLWin.dpy, GLWin.win); XGrabKeyboard(GLWin.dpy, GLWin.win, True, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabPointer(GLWin.dpy, GLWin.win, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, GLWin.win, None, CurrentTime); } else { /* create a window in window mode*/ GLWin.attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask; GLWin.win = XCreateWindow(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen), 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &GLWin.attr); /* only set window title and handle wm_delete_events if in windowed mode */ wmDelete = XInternAtom(GLWin.dpy, "WM_DELETE_WINDOW", True); XSetWMProtocols(GLWin.dpy, GLWin.win, &wmDelete, 1); XSetStandardProperties(GLWin.dpy, GLWin.win, title, title, None, NULL, 0, NULL); XMapRaised(GLWin.dpy, GLWin.win); } /* connect the glx-context to the window */ glXMakeCurrent(GLWin.dpy, GLWin.win, GLWin.ctx); XGetGeometry(GLWin.dpy, GLWin.win, &winDummy, &GLWin.x, &GLWin.y, &GLWin.width, &GLWin.height, &borderDummy, &GLWin.depth); printf("Depth %d\n", GLWin.depth); if (glXIsDirect(GLWin.dpy, GLWin.ctx)) printf("Congrats, you have Direct Rendering!\n"); else printf("Sorry, no Direct Rendering possible!\n"); initGL(); return True; }
bool CreateWindowGL (GL_Window* window) { XVisualInfo *vi; Colormap cmap; int dpyWidth, dpyHeight; int i; int glxMajorVersion, glxMinorVersion; int vidModeMajorVersion, vidModeMinorVersion; XF86VidModeModeInfo **modes; int modeNum; int bestMode; Atom wmDelete; Window winDummy; unsigned int borderDummy; int x, y; bestMode = 0; window->init.dpy = XOpenDisplay( NULL ); window->init.screen = DefaultScreen( window->init.dpy ); XF86VidModeQueryVersion( window->init.dpy, &vidModeMajorVersion, &vidModeMinorVersion ); printf( "XF86VMExt-Version %d.%d\n", vidModeMajorVersion, vidModeMinorVersion ); XF86VidModeGetAllModeLines( window->init.dpy, window->init.screen, &modeNum, &modes ); window->init.deskMode = *modes[0]; for( i=0;i<modeNum;i++ ) { if( (modes[i]->hdisplay == window->init.width) && (modes[i]->vdisplay == window->init.height) ) bestMode = i; } vi = glXChooseVisual( window->init.dpy, window->init.screen, attrListDbl ); if( vi == NULL ) { vi = glXChooseVisual( window->init.dpy, window->init.screen, attrListSgl ); window->init.doubleBuffered = false; printf( "Single Buffered visual\n" ); } else { window->init.doubleBuffered = true; printf( "Double Buffered visual\n" ); } glXQueryVersion( window->init.dpy, &glxMajorVersion, &glxMinorVersion ); printf( "glx-version %d.%d\n", glxMajorVersion, glxMinorVersion ); window->init.ctx = glXCreateContext( window->init.dpy, vi, 0, GL_TRUE ); cmap = XCreateColormap( window->init.dpy, RootWindow( window->init.dpy, vi->screen ), vi->visual, AllocNone ); window->init.attr.colormap = cmap; window->init.attr.border_pixel = 0; if( window->init.isFullScreen ) { XF86VidModeSwitchToMode( window->init.dpy, window->init.screen, modes[bestMode] ); XF86VidModeSetViewPort( window->init.dpy, window->init.screen, 0, 0 ); dpyWidth = modes[bestMode]->hdisplay; dpyHeight = modes[bestMode]->vdisplay; XFree( modes ); window->init.attr.override_redirect = true; window->init.attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | StructureNotifyMask | PointerMotionMask; window->init.win = XCreateWindow( window->init.dpy, RootWindow( window->init.dpy, vi->screen ), 0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &window->init.attr ); XWarpPointer( window->init.dpy, None, window->init.win, 0, 0, 0, 0, 0, 0 ); XMapRaised( window->init.dpy, window->init.win ); XGrabKeyboard( window->init.dpy, window->init.win, True, GrabModeAsync, GrabModeAsync, CurrentTime ); XGrabPointer( window->init.dpy, window->init.win, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, window->init.win, None, CurrentTime ); } else { window->init.attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | StructureNotifyMask | PointerMotionMask; window->init.win = XCreateWindow( window->init.dpy, RootWindow( window->init.dpy, vi->screen ), 0, 0, window->init.width, window->init.height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &window->init.attr ); wmDelete = XInternAtom( window->init.dpy, "WM_DELETE_WINDOW", True ); XSetWMProtocols( window->init.dpy, window->init.win, &wmDelete, 1 ); XSetStandardProperties( window->init.dpy, window->init.win, window->init.title, window->init.title, None, NULL, 0, NULL ); XMapRaised( window->init.dpy, window->init.win ); } glXMakeCurrent( window->init.dpy, window->init.win, window->init.ctx ); XGetGeometry( window->init.dpy, window->init.win, &winDummy, &x, &y, &window->init.width, &window->init.height, &borderDummy, &window->init.depth ); if( glXIsDirect( window->init.dpy, window->init.ctx ) ) printf( "Direct rendering\n" ); else printf( "Not Direct rendering\n" ); return true; }
static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format) { int x_off, y_off; int wanted_width, wanted_height; static unsigned char *vo_dga_base; static int prev_width, prev_height; #ifdef HAVE_DGA2 // needed to change DGA video mode int mX = VO_DGA_INVALID_RES, mY = VO_DGA_INVALID_RES, mVBI = 100000, mMaxY = 0, i, j = 0; int dga_modenum; XDGAMode *modeline; XDGADevice *dgadevice; #else #ifdef HAVE_XF86VM unsigned int vm_event, vm_error; unsigned int vm_ver, vm_rev; int i, j = 0, have_vm = 0; int mX = VO_DGA_INVALID_RES, mY = VO_DGA_INVALID_RES, mVBI = 100000, mMaxY = 0, dga_modenum; #endif int bank, ram; #endif vo_dga_src_format = format; wanted_width = d_width; wanted_height = d_height; if (!wanted_height) wanted_height = height; if (!wanted_width) wanted_width = width; if (!vo_dbpp) { if ((format & IMGFMT_BGR_MASK) == IMGFMT_BGR) { vo_dga_src_mode = vd_ModeValid(format & 0xff); } } else { vo_dga_src_mode = vd_ModeValid(vo_dbpp); } vo_dga_hw_mode = SRC_MODE.vdm_hw_mode; if (!vo_dga_src_mode) { mp_msg(MSGT_VO, MSGL_ERR, "vo_dga: unsupported video format!\n"); return 1; } vo_dga_vp_width = vo_screenwidth; vo_dga_vp_height = vo_screenheight; mp_msg(MSGT_VO, MSGL_V, "vo_dga: XServer res: %dx%d\n", vo_dga_vp_width, vo_dga_vp_height); // choose a suitable mode ... #ifdef HAVE_DGA2 // Code to change the video mode added by Michael Graffam // [email protected] mp_msg(MSGT_VO, MSGL_V, "vo_dga: vo_modelines=%p, vo_modecount=%d\n", vo_modelines, vo_modecount); if (vo_modelines == NULL) { mp_msg(MSGT_VO, MSGL_ERR, "vo_dga: can't get modelines\n"); return 1; } mp_msg(MSGT_VO, MSGL_INFO, "vo_dga: DGA 2.0 available :-) Can switch resolution AND depth!\n"); for (i = 0; i < vo_modecount; i++) { if (vd_ModeEqual(vo_modelines[i].depth, vo_modelines[i].bitsPerPixel, vo_modelines[i].redMask, vo_modelines[i].greenMask, vo_modelines[i].blueMask, vo_dga_hw_mode)) { mp_msg(MSGT_VO, MSGL_V, "maxy: %4d, depth: %2d, %4dx%4d, ", vo_modelines[i].maxViewportY, vo_modelines[i].depth, vo_modelines[i].imageWidth, vo_modelines[i].imageHeight); if (check_res (i, wanted_width, wanted_height, vo_modelines[i].depth, vo_modelines[i].viewportWidth, vo_modelines[i].viewportHeight, (unsigned) vo_modelines[i].verticalRefresh, vo_modelines[i].maxViewportY, &mX, &mY, &mVBI, &mMaxY)) j = i; } } mp_msg(MSGT_VO, MSGL_INFO, "vo_dga: Selected hardware mode %4d x %4d @ %3d Hz @ depth %2d, bitspp %2d.\n", mX, mY, mVBI, HW_MODE.vdm_depth, HW_MODE.vdm_bitspp); mp_msg(MSGT_VO, MSGL_INFO, "vo_dga: Video parameters by codec: %3d x %3d, depth %2d, bitspp %2d.\n", width, height, SRC_MODE.vdm_depth, SRC_MODE.vdm_bitspp); vo_dga_vp_width = mX; vo_dga_vp_height = mY; if ((flags & VOFLAG_SWSCALE) || (flags & VOFLAG_FULLSCREEN)) { /* -zoom or -fs */ scale_dstW = (d_width + 7) & ~7; scale_dstH = d_height; scale_srcW = width; scale_srcH = height; aspect_save_screenres(mX, mY); aspect_save_orig(scale_srcW, scale_srcH); aspect_save_prescale(scale_dstW, scale_dstH); if (flags & VOFLAG_FULLSCREEN) /* -fs */ aspect(&scale_dstW, &scale_dstH, A_ZOOM); else if (flags & VOFLAG_SWSCALE) /* -fs */ aspect(&scale_dstW, &scale_dstH, A_NOZOOM); mp_msg(MSGT_VO, MSGL_INFO, "vo_dga: Aspect corrected size for SwScaler: %4d x %4d.\n", scale_dstW, scale_dstH); /* XXX this is a hack, but I'm lazy ;-) :: atmos */ width = scale_dstW; height = scale_dstH; } vo_dga_width = vo_modelines[j].bytesPerScanline / HW_MODE.vdm_bytespp; dga_modenum = vo_modelines[j].num; modeline = vo_modelines + j; #else #ifdef HAVE_XF86VM mp_msg(MSGT_VO, MSGL_INFO, "vo_dga: DGA 1.0 compatibility code: Using XF86VidMode for mode switching!\n"); if (XF86VidModeQueryExtension(mDisplay, &vm_event, &vm_error)) { XF86VidModeQueryVersion(mDisplay, &vm_ver, &vm_rev); mp_msg(MSGT_VO, MSGL_INFO, "vo_dga: XF86VidMode Extension v%i.%i\n", vm_ver, vm_rev); have_vm = 1; } else { mp_msg(MSGT_VO, MSGL_ERR, "vo_dga: XF86VidMode Extension not available.\n"); } #define GET_VREFRESH(dotclk, x, y)( (((dotclk)/(x))*1000)/(y) ) if (have_vm) { int modecount; XF86VidModeGetAllModeLines(mDisplay, mScreen, &modecount, &vo_dga_vidmodes); if (vo_dga_vidmodes != NULL) { for (i = 0; i < modecount; i++) { if (check_res(i, wanted_width, wanted_height, vo_dga_modes[vo_dga_hw_mode].vdm_depth, vo_dga_vidmodes[i]->hdisplay, vo_dga_vidmodes[i]->vdisplay, GET_VREFRESH(vo_dga_vidmodes[i]->dotclock, vo_dga_vidmodes[i]->htotal, vo_dga_vidmodes[i]->vtotal), 0, &mX, &mY, &mVBI, &mMaxY)) j = i; } mp_msg(MSGT_VO, MSGL_INFO, "vo_dga: Selected video mode %4d x %4d @ %3d Hz @ depth %2d, bitspp %2d, video %3d x %3d.\n", mX, mY, mVBI, vo_dga_modes[vo_dga_hw_mode].vdm_depth, vo_dga_modes[vo_dga_hw_mode].vdm_bitspp, width, height); } else { mp_msg(MSGT_VO, MSGL_INFO, "vo_dga: XF86VidMode returned no screens - using current resolution.\n"); } dga_modenum = j; vo_dga_vp_width = mX; vo_dga_vp_height = mY; } #else mp_msg(MSGT_VO, MSGL_INFO, "vo_dga: Only have DGA 1.0 extension and no XF86VidMode :-(\n"); mp_msg(MSGT_VO, MSGL_INFO, " Thus, resolution switching is NOT possible.\n"); #endif #endif vo_dga_src_width = width; vo_dga_src_height = height; if (vo_dga_src_width > vo_dga_vp_width || vo_dga_src_height > vo_dga_vp_height) { mp_msg(MSGT_VO, MSGL_ERR, "vo_dga: Sorry, video larger than viewport is not yet supported!\n"); // ugly, do something nicer in the future ... #ifndef HAVE_DGA2 #ifdef HAVE_XF86VM if (vo_dga_vidmodes) { XFree(vo_dga_vidmodes); vo_dga_vidmodes = NULL; } #endif #endif return 1; } if (vo_dga_vp_width == VO_DGA_INVALID_RES) { mp_msg(MSGT_VO, MSGL_ERR, "vo_dga: Something is wrong with your DGA. There doesn't seem to be a\n" " single suitable mode!\n" " Please file a bug report (see DOCS/HTML/en/bugreports.html)\n"); #ifndef HAVE_DGA2 #ifdef HAVE_XF86VM if (vo_dga_vidmodes) { XFree(vo_dga_vidmodes); vo_dga_vidmodes = NULL; } #endif #endif return 1; } // now let's start the DGA thing if (!vo_config_count || width != prev_width || height != prev_height) { #ifdef HAVE_DGA2 if (!XDGAOpenFramebuffer(mDisplay, mScreen)) { mp_msg(MSGT_VO, MSGL_ERR, "vo_dga: Framebuffer mapping failed!!!\n"); return 1; } dgadevice = XDGASetMode(mDisplay, mScreen, dga_modenum); XDGASync(mDisplay, mScreen); vo_dga_base = dgadevice->data; XFree(dgadevice); XDGASetViewport(mDisplay, mScreen, 0, 0, XDGAFlipRetrace); #else #ifdef HAVE_XF86VM if (have_vm) { XF86VidModeLockModeSwitch(mDisplay, mScreen, 0); // Two calls are needed to switch modes on my ATI Rage 128. Why? // for riva128 one call is enough! XF86VidModeSwitchToMode(mDisplay, mScreen, vo_dga_vidmodes[dga_modenum]); XF86VidModeSwitchToMode(mDisplay, mScreen, vo_dga_vidmodes[dga_modenum]); } #endif XF86DGAGetViewPortSize(mDisplay, mScreen, &vo_dga_vp_width, &vo_dga_vp_height); XF86DGAGetVideo(mDisplay, mScreen, (char **) &vo_dga_base, &vo_dga_width, &bank, &ram); XF86DGADirectVideo(mDisplay, mScreen, XF86DGADirectGraphics | XF86DGADirectMouse | XF86DGADirectKeyb); XF86DGASetViewPort(mDisplay, mScreen, 0, 0); #endif } // do some more checkings here ... mp_msg(MSGT_VO, MSGL_V, "vo_dga: bytes/line: %d, screen res: %dx%d, depth: %d, base: %p, bpp: %d\n", vo_dga_width, vo_dga_vp_width, vo_dga_vp_height, HW_MODE.vdm_bytespp, vo_dga_base, HW_MODE.vdm_bitspp); x_off = (vo_dga_vp_width - vo_dga_src_width) >> 1; y_off = (vo_dga_vp_height - vo_dga_src_height) >> 1; vo_dga_bytes_per_line = vo_dga_src_width * HW_MODE.vdm_bytespp; vo_dga_lines = vo_dga_src_height; vo_dga_src_offset = 0; vo_dga_vp_offset = (y_off * vo_dga_width + x_off) * HW_MODE.vdm_bytespp; vo_dga_vp_skip = (vo_dga_width - vo_dga_src_width) * HW_MODE.vdm_bytespp; // todo mp_msg(MSGT_VO, MSGL_V, "vo_dga: vp_off=%d, vp_skip=%d, bpl=%d\n", vo_dga_vp_offset, vo_dga_vp_skip, vo_dga_bytes_per_line); XGrabKeyboard(mDisplay, DefaultRootWindow(mDisplay), True, GrabModeAsync, GrabModeAsync, CurrentTime); if (vo_grabpointer) XGrabPointer(mDisplay, DefaultRootWindow(mDisplay), True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); if (!vo_config_count || width != prev_width || height != prev_height) { init_video_buffers(vo_dga_base, vo_dga_vp_height, vo_dga_width * HW_MODE.vdm_bytespp, #ifdef HAVE_DGA2 modeline->maxViewportY, #else vo_dga_vp_height, #endif vo_doublebuffering); prev_width = width; prev_height = height; } mp_msg(MSGT_VO, MSGL_V, "vo_dga: Using %d frame buffer%s.\n", vo_dga_nr_video_buffers, vo_dga_nr_video_buffers == 1 ? "" : "s"); vo_dga_is_running = 1; return 0; }
rserr_t GLimp_SetMode( int mode, int colorbits, bool fullscreen ) { if ( !XInitThreads() ) { common->Printf( "...XInitThreads() failed, disabling r_smp\n" ); Cvar_Set( "r_smp", "0" ); } // set up our custom error handler for X failures XSetErrorHandler( &qXErrorHandler ); if ( fullscreen && in_nograb->value ) { common->Printf( "Fullscreen not allowed with in_nograb 1\n" ); Cvar_Set( "r_fullscreen", "0" ); r_fullscreen->modified = false; fullscreen = false; } common->Printf( "...setting mode %d:", mode ); if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) ) { common->Printf( " invalid mode\n" ); return RSERR_INVALID_MODE; } common->Printf( " %d %d\n", glConfig.vidWidth, glConfig.vidHeight ); // open the display if ( !( dpy = XOpenDisplay( NULL ) ) ) { fprintf( stderr, "Error couldn't open the X display\n" ); return RSERR_INVALID_MODE; } scrnum = DefaultScreen( dpy ); Window root = RootWindow( dpy, scrnum ); // Get video mode list if ( !XF86VidModeQueryVersion( dpy, &vidmode_MajorVersion, &vidmode_MinorVersion ) ) { vidmode_ext = false; } else { common->Printf( "Using XFree86-VidModeExtension Version %d.%d\n", vidmode_MajorVersion, vidmode_MinorVersion ); vidmode_ext = true; } // Check for DGA int dga_MajorVersion = 0; int dga_MinorVersion = 0; if ( in_dgamouse->value ) { if ( !XF86DGAQueryVersion( dpy, &dga_MajorVersion, &dga_MinorVersion ) ) { // unable to query, probalby not supported common->Printf( "Failed to detect XF86DGA Mouse\n" ); Cvar_Set( "in_dgamouse", "0" ); } else { common->Printf( "XF86DGA Mouse (Version %d.%d) initialized\n", dga_MajorVersion, dga_MinorVersion ); } } int actualWidth = glConfig.vidWidth; int actualHeight = glConfig.vidHeight; if ( vidmode_ext ) { int best_fit, best_dist, dist, x, y; XF86VidModeGetAllModeLines( dpy, scrnum, &num_vidmodes, &vidmodes ); // Are we going fullscreen? If so, let's change video mode if ( fullscreen ) { best_dist = 9999999; best_fit = -1; for ( int i = 0; i < num_vidmodes; i++ ) { if ( glConfig.vidWidth > vidmodes[ i ]->hdisplay || glConfig.vidHeight > vidmodes[ i ]->vdisplay ) { continue; } x = glConfig.vidWidth - vidmodes[ i ]->hdisplay; y = glConfig.vidHeight - vidmodes[ i ]->vdisplay; dist = ( x * x ) + ( y * y ); if ( dist < best_dist ) { best_dist = dist; best_fit = i; } } if ( best_fit != -1 ) { actualWidth = vidmodes[ best_fit ]->hdisplay; actualHeight = vidmodes[ best_fit ]->vdisplay; // change to the mode XF86VidModeSwitchToMode( dpy, scrnum, vidmodes[ best_fit ] ); vidmode_active = true; // Move the viewport to top left XF86VidModeSetViewPort( dpy, scrnum, 0, 0 ); common->Printf( "XFree86-VidModeExtension Activated at %dx%d\n", actualWidth, actualHeight ); } else { fullscreen = 0; common->Printf( "XFree86-VidModeExtension: No acceptable modes found\n" ); } } else { common->Printf( "XFree86-VidModeExtension: Ignored on non-fullscreen\n" ); } } if ( !colorbits ) { colorbits = !r_colorbits->value ? 24 : r_colorbits->value; } int depthbits = !r_depthbits->value ? 24 : r_depthbits->value; int stencilbits = r_stencilbits->value; XVisualInfo* visinfo = NULL; for ( int i = 0; i < 16; i++ ) { // 0 - default // 1 - minus colorbits // 2 - minus depthbits // 3 - minus stencil if ( ( i % 4 ) == 0 && i ) { // one pass, reduce switch ( i / 4 ) { case 2: if ( colorbits == 24 ) { colorbits = 16; } break; case 1: if ( depthbits == 24 ) { depthbits = 16; } else if ( depthbits == 16 ) { depthbits = 8; } break; case 3: if ( stencilbits == 24 ) { stencilbits = 16; } else if ( stencilbits == 16 ) { stencilbits = 8; } break; } } int tcolorbits = colorbits; int tdepthbits = depthbits; int tstencilbits = stencilbits; if ( ( i % 4 ) == 3 ) { // reduce colorbits if ( tcolorbits == 24 ) { tcolorbits = 16; } } if ( ( i % 4 ) == 2 ) { // reduce depthbits if ( tdepthbits == 24 ) { tdepthbits = 16; } else if ( tdepthbits == 16 ) { tdepthbits = 8; } } if ( ( i % 4 ) == 1 ) { // reduce stencilbits if ( tstencilbits == 24 ) { tstencilbits = 16; } else if ( tstencilbits == 16 ) { tstencilbits = 8; } else { tstencilbits = 0; } } int attrib[] = { GLX_RGBA, // 0 GLX_RED_SIZE, 4, // 1, 2 GLX_GREEN_SIZE, 4, // 3, 4 GLX_BLUE_SIZE, 4, // 5, 6 GLX_DOUBLEBUFFER, // 7 GLX_DEPTH_SIZE, 1, // 8, 9 GLX_STENCIL_SIZE, 1, // 10, 11 //GLX_SAMPLES_SGIS, 4, /* for better AA */ None }; // these match in the array enum { ATTR_RED_IDX = 2, ATTR_GREEN_IDX = 4, ATTR_BLUE_IDX = 6, ATTR_DEPTH_IDX = 9, ATTR_STENCIL_IDX = 11 }; if ( tcolorbits == 24 ) { attrib[ ATTR_RED_IDX ] = 8; attrib[ ATTR_GREEN_IDX ] = 8; attrib[ ATTR_BLUE_IDX ] = 8; } else { // must be 16 bit attrib[ ATTR_RED_IDX ] = 4; attrib[ ATTR_GREEN_IDX ] = 4; attrib[ ATTR_BLUE_IDX ] = 4; } attrib[ ATTR_DEPTH_IDX ] = tdepthbits; // default to 24 depth attrib[ ATTR_STENCIL_IDX ] = tstencilbits; visinfo = glXChooseVisual( dpy, scrnum, attrib ); if ( !visinfo ) { continue; } common->Printf( "Using %d/%d/%d Color bits, %d depth, %d stencil display.\n", attrib[ ATTR_RED_IDX ], attrib[ ATTR_GREEN_IDX ], attrib[ ATTR_BLUE_IDX ], attrib[ ATTR_DEPTH_IDX ], attrib[ ATTR_STENCIL_IDX ] ); glConfig.colorBits = tcolorbits; glConfig.depthBits = tdepthbits; glConfig.stencilBits = tstencilbits; break; } if ( !visinfo ) { common->Printf( "Couldn't get a visual\n" ); return RSERR_INVALID_MODE; } // Window attributes XSetWindowAttributes attr; unsigned long mask; attr.background_pixel = BlackPixel( dpy, scrnum ); attr.border_pixel = 0; attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone ); attr.event_mask = X_MASK; if ( vidmode_active ) { mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore | CWEventMask | CWOverrideRedirect; attr.override_redirect = True; attr.backing_store = NotUseful; attr.save_under = False; } else { mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; } win = XCreateWindow( dpy, root, 0, 0, actualWidth, actualHeight, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr ); XStoreName( dpy, win, R_GetTitleForWindow() ); /* GH: Don't let the window be resized */ XSizeHints sizehints; sizehints.flags = PMinSize | PMaxSize; sizehints.min_width = sizehints.max_width = actualWidth; sizehints.min_height = sizehints.max_height = actualHeight; XSetWMNormalHints( dpy, win, &sizehints ); XMapWindow( dpy, win ); if ( vidmode_active ) { XMoveWindow( dpy, win, 0, 0 ); //XRaiseWindow(dpy, win); //XWarpPointer(dpy, None, win, 0, 0, 0, 0, 0, 0); //XFlush(dpy); // Move the viewport to top left //XF86VidModeSetViewPort(dpy, scrnum, 0, 0); } // hook to window close wm_protocols = XInternAtom( dpy, "WM_PROTOCOLS", False ); wm_delete_window = XInternAtom( dpy, "WM_DELETE_WINDOW", False ); XSetWMProtocols( dpy, win, &wm_delete_window, 1 ); XFlush( dpy ); XSync( dpy, False ); // bk001130 - from cvs1.17 (mkv) ctx = glXCreateContext( dpy, visinfo, NULL, True ); XSync( dpy, False ); // bk001130 - from cvs1.17 (mkv) /* GH: Free the visinfo after we're done with it */ XFree( visinfo ); glXMakeCurrent( dpy, win, ctx ); glConfig.deviceSupportsGamma = false; if ( vidmode_ext ) { if ( vidmode_MajorVersion < GAMMA_MINMAJOR || ( vidmode_MajorVersion == GAMMA_MINMAJOR && vidmode_MinorVersion < GAMMA_MINMINOR ) ) { common->Printf( "XF86 Gamma extension not supported in this version\n" ); } else { XF86VidModeGetGamma( dpy, scrnum, &vidmode_InitialGamma ); common->Printf( "XF86 Gamma extension initialized\n" ); glConfig.deviceSupportsGamma = true; } } // Check for software GL implementation. const char* glstring = ( char* )glGetString( GL_RENDERER ); if ( !String::ICmp( glstring, "Mesa X11" ) || !String::ICmp( glstring, "Mesa GLX Indirect" ) ) { if ( !r_allowSoftwareGL->integer ) { common->Printf( "\n\n***********************************************************\n" ); common->Printf( " You are using software Mesa (no hardware acceleration)!\n" ); common->Printf( " If this is intentional, add\n" ); common->Printf( " \"+set r_allowSoftwareGL 1\"\n" ); common->Printf( " to the command line when starting the game.\n" ); common->Printf( "***********************************************************\n" ); GLimp_Shutdown(); return RSERR_INVALID_MODE; } else { common->Printf( "...using software Mesa (r_allowSoftwareGL==1).\n" ); } } GLW_GenDefaultLists(); return RSERR_OK; }
int main(int argc, char *argv[]) { int i, ret; char *displayname = NULL; Display *dpy; float gam = -1., rgam = -1., ggam = -1., bgam = -1.; XF86VidModeGamma gamma; Bool quiet = False; int screen = -1; ProgramName = argv[0]; for (i = 1; i < argc; i++) { char *arg = argv[i]; if (arg[0] == '-') { if (isabbreviation ("-display", arg, 1)) { if (++i >= argc) Syntax ("-display requires an argument"); displayname = argv[i]; continue; } else if (isabbreviation ("-quiet", arg, 1)) { quiet = True; continue; } else if (isabbreviation ("-version", arg, 1)) { puts(PACKAGE_STRING); exit(0); } else if (isabbreviation ("-screen", arg, 1)) { if (++i >= argc) Syntax ("-screen requires an argument"); screen = atoi(argv[i]); continue; } else if (isabbreviation ("-gamma", arg, 2)) { if (++i >= argc) Syntax ("-gamma requires an argument"); if ((rgam >= 0.) || (ggam >= 0.) || (bgam >= 0.)) Syntax ("-gamma cannot be used with -rgamma, -ggamma, or -bgamma"); gam = (float)atof(argv[i]); if ((gam < GAMMA_MIN) || (gam > GAMMA_MAX)) { fprintf(stderr, "Gamma values must be between %6.3f and %6.3f\n", GAMMA_MIN, GAMMA_MAX); exit(1); } continue; } else if (isabbreviation ("-rgamma", arg, 2)) { if (++i >= argc) Syntax ("-rgamma requires an argument"); if (gam >= 0.) Syntax ("cannot set both -gamma and -rgamma"); rgam = (float)atof(argv[i]); if ((rgam < GAMMA_MIN) || (rgam > GAMMA_MAX)) { fprintf(stderr, "Gamma values must be between %6.3f and %6.3f\n", GAMMA_MIN, GAMMA_MAX); exit(1); } continue; } else if (isabbreviation ("-ggamma", arg, 2)) { if (++i >= argc) Syntax ("-ggamma requires an argument"); if (gam >= 0.) Syntax ("cannot set both -gamma and -ggamma"); ggam = (float)atof(argv[i]); if ((ggam < GAMMA_MIN) || (ggam > GAMMA_MAX)) { fprintf(stderr, "Gamma values must be between %6.3f and %6.3f\n", GAMMA_MIN, GAMMA_MAX); exit(1); } continue; } else if (isabbreviation ("-bgamma", arg, 2)) { if (++i >= argc) Syntax ("-bgamma requires an argument"); if (gam >= 0.) Syntax ("cannot set both -gamma and -bgamma"); bgam = (float)atof(argv[i]); if ((bgam < GAMMA_MIN) || (bgam > GAMMA_MAX)) { fprintf(stderr, "Gamma values must be between %6.3f and %6.3f\n", GAMMA_MIN, GAMMA_MAX); exit(1); } continue; } else { if (!isabbreviation ("-help", arg, 1)) fprintf (stderr, "%s: unrecognized argument %s\n\n", ProgramName, arg); Syntax (NULL); } } else { fprintf (stderr, "%s: unrecognized argument %s\n\n", ProgramName, arg); Syntax (NULL); } } if ((dpy = XOpenDisplay(displayname)) == NULL) { fprintf (stderr, "%s: unable to open display '%s'\n", ProgramName, XDisplayName (displayname)); exit(1); } else if (screen == -1) screen = DefaultScreen(dpy); if (!XF86VidModeQueryVersion(dpy, &MajorVersion, &MinorVersion)) { fprintf(stderr, "Unable to query video extension version\n"); exit(2); } if (!XF86VidModeQueryExtension(dpy, &EventBase, &ErrorBase)) { fprintf(stderr, "Unable to query video extension information\n"); exit(2); } /* Fail if the extension version in the server is too old */ if (MajorVersion < MINMAJOR || (MajorVersion == MINMAJOR && MinorVersion < MINMINOR)) { fprintf(stderr, "Xserver is running an old XFree86-VidModeExtension version" " (%d.%d)\n", MajorVersion, MinorVersion); fprintf(stderr, "Minimum required version is %d.%d\n", MINMAJOR, MINMINOR); exit(2); } if (!XF86VidModeGetGamma(dpy, screen, &gamma)) { fprintf(stderr, "Unable to query gamma correction\n"); XCloseDisplay (dpy); exit (2); } else if (!quiet) fprintf(stderr, "-> Red %6.3f, Green %6.3f, Blue %6.3f\n", gamma.red, gamma.green, gamma.blue); ret = 0; if (gam >= 0.) { gamma.red = gam; gamma.green = gam; gamma.blue = gam; if (!XF86VidModeSetGamma(dpy, screen, &gamma)) { fprintf(stderr, "Unable to set gamma correction\n"); ret = 2; } else { if (!XF86VidModeGetGamma(dpy, screen, &gamma)) { fprintf(stderr, "Unable to query gamma correction\n"); ret = 2; } else if (!quiet) fprintf(stderr, "<- Red %6.3f, Green %6.3f, Blue %6.3f\n", gamma.red, gamma.green, gamma.blue); } } else if ((rgam >= 0.) || (ggam >= 0.) || (bgam >= 0.)) { if (rgam >= 0.) gamma.red = rgam; if (ggam >= 0.) gamma.green = ggam; if (bgam >= 0.) gamma.blue = bgam; if (!XF86VidModeSetGamma(dpy, screen, &gamma)) { fprintf(stderr, "Unable to set gamma correction\n"); ret = 2; } else { if (!XF86VidModeGetGamma(dpy, screen, &gamma)) { fprintf(stderr, "Unable to query gamma correction\n"); ret = 2; } else if (!quiet) fprintf(stderr, "<- Red %6.3f, Green %6.3f, Blue %6.3f\n", gamma.red, gamma.green, gamma.blue); } } XCloseDisplay (dpy); exit (ret); }
/* ** GLW_SetMode */ int GLW_SetMode( const char *drivername, int mode, qboolean fullscreen ) { int attrib[] = { GLX_RGBA, // 0 GLX_RED_SIZE, 4, // 1, 2 GLX_GREEN_SIZE, 4, // 3, 4 GLX_BLUE_SIZE, 4, // 5, 6 GLX_DOUBLEBUFFER, // 7 GLX_DEPTH_SIZE, 1, // 8, 9 GLX_STENCIL_SIZE, 1, // 10, 11 None }; // these match in the array #define ATTR_RED_IDX 2 #define ATTR_GREEN_IDX 4 #define ATTR_BLUE_IDX 6 #define ATTR_DEPTH_IDX 9 #define ATTR_STENCIL_IDX 11 Window root; XVisualInfo *visinfo; XSetWindowAttributes attr; XSizeHints sizehints; unsigned long mask; int colorbits, depthbits, stencilbits; int tcolorbits, tdepthbits, tstencilbits; int dga_MajorVersion, dga_MinorVersion; int actualWidth, actualHeight; int i; const char* glstring; // bk001130 - from cvs1.17 (mkv) ri.Printf( PRINT_ALL, "Initializing OpenGL display\n" ); ri.Printf( PRINT_ALL, "...setting mode %d:", mode ); if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) ) { ri.Printf( PRINT_ALL, " invalid mode\n" ); return RSERR_INVALID_MODE; } ri.Printf( PRINT_ALL, " %d %d\n", glConfig.vidWidth, glConfig.vidHeight ); if ( !( dpy = XOpenDisplay( NULL ) ) ) { fprintf( stderr, "Error couldn't open the X display\n" ); return RSERR_INVALID_MODE; } scrnum = DefaultScreen( dpy ); root = RootWindow( dpy, scrnum ); actualWidth = glConfig.vidWidth; actualHeight = glConfig.vidHeight; // Get video mode list if ( !XF86VidModeQueryVersion( dpy, &vidmode_MajorVersion, &vidmode_MinorVersion ) ) { vidmode_ext = qfalse; } else { ri.Printf( PRINT_ALL, "Using XFree86-VidModeExtension Version %d.%d\n", vidmode_MajorVersion, vidmode_MinorVersion ); vidmode_ext = qtrue; } // Check for DGA dga_MajorVersion = 0, dga_MinorVersion = 0; if ( in_dgamouse->value ) { if ( !XF86DGAQueryVersion( dpy, &dga_MajorVersion, &dga_MinorVersion ) ) { // unable to query, probalby not supported ri.Printf( PRINT_ALL, "Failed to detect XF86DGA Mouse\n" ); ri.Cvar_Set( "in_dgamouse", "0" ); } else { ri.Printf( PRINT_ALL, "XF86DGA Mouse (Version %d.%d) initialized\n", dga_MajorVersion, dga_MinorVersion ); } } if ( vidmode_ext ) { int best_fit, best_dist, dist, x, y; XF86VidModeGetAllModeLines( dpy, scrnum, &num_vidmodes, &vidmodes ); // Are we going fullscreen? If so, let's change video mode if ( fullscreen ) { best_dist = 9999999; best_fit = -1; for ( i = 0; i < num_vidmodes; i++ ) { if ( glConfig.vidWidth > vidmodes[i]->hdisplay || glConfig.vidHeight > vidmodes[i]->vdisplay ) { continue; } x = glConfig.vidWidth - vidmodes[i]->hdisplay; y = glConfig.vidHeight - vidmodes[i]->vdisplay; dist = ( x * x ) + ( y * y ); if ( dist < best_dist ) { best_dist = dist; best_fit = i; } } if ( best_fit != -1 ) { actualWidth = vidmodes[best_fit]->hdisplay; actualHeight = vidmodes[best_fit]->vdisplay; // change to the mode XF86VidModeSwitchToMode( dpy, scrnum, vidmodes[best_fit] ); vidmode_active = qtrue; // Move the viewport to top left XF86VidModeSetViewPort( dpy, scrnum, 0, 0 ); ri.Printf( PRINT_ALL, "XFree86-VidModeExtension Activated at %dx%d\n", actualWidth, actualHeight ); } else { fullscreen = 0; ri.Printf( PRINT_ALL, "XFree86-VidModeExtension: No acceptable modes found\n" ); } } else { ri.Printf( PRINT_ALL, "XFree86-VidModeExtension: Ignored on non-fullscreen/Voodoo\n" ); } } if ( !r_colorbits->value ) { colorbits = 24; } else { colorbits = r_colorbits->value; } if ( !Q_stricmp( r_glDriver->string, _3DFX_DRIVER_NAME ) ) { colorbits = 16; } if ( !r_depthbits->value ) { depthbits = 24; } else { depthbits = r_depthbits->value; } stencilbits = r_stencilbits->value; for ( i = 0; i < 16; i++ ) { // 0 - default // 1 - minus colorbits // 2 - minus depthbits // 3 - minus stencil if ( ( i % 4 ) == 0 && i ) { // one pass, reduce switch ( i / 4 ) { case 2: if ( colorbits == 24 ) { colorbits = 16; } break; case 1: if ( depthbits == 24 ) { depthbits = 16; } else if ( depthbits == 16 ) { depthbits = 8; } case 3: if ( stencilbits == 24 ) { stencilbits = 16; } else if ( stencilbits == 16 ) { stencilbits = 8; } } } tcolorbits = colorbits; tdepthbits = depthbits; tstencilbits = stencilbits; if ( ( i % 4 ) == 3 ) { // reduce colorbits if ( tcolorbits == 24 ) { tcolorbits = 16; } } if ( ( i % 4 ) == 2 ) { // reduce depthbits if ( tdepthbits == 24 ) { tdepthbits = 16; } else if ( tdepthbits == 16 ) { tdepthbits = 8; } } if ( ( i % 4 ) == 1 ) { // reduce stencilbits if ( tstencilbits == 24 ) { tstencilbits = 16; } else if ( tstencilbits == 16 ) { tstencilbits = 8; } else { tstencilbits = 0; } } if ( tcolorbits == 24 ) { attrib[ATTR_RED_IDX] = 8; attrib[ATTR_GREEN_IDX] = 8; attrib[ATTR_BLUE_IDX] = 8; } else { // must be 16 bit attrib[ATTR_RED_IDX] = 4; attrib[ATTR_GREEN_IDX] = 4; attrib[ATTR_BLUE_IDX] = 4; } attrib[ATTR_DEPTH_IDX] = tdepthbits; // default to 24 depth attrib[ATTR_STENCIL_IDX] = tstencilbits; visinfo = qglXChooseVisual( dpy, scrnum, attrib ); if ( !visinfo ) { continue; } ri.Printf( PRINT_ALL, "Using %d/%d/%d Color bits, %d depth, %d stencil display.\n", attrib[ATTR_RED_IDX], attrib[ATTR_GREEN_IDX], attrib[ATTR_BLUE_IDX], attrib[ATTR_DEPTH_IDX], attrib[ATTR_STENCIL_IDX] ); glConfig.colorBits = tcolorbits; glConfig.depthBits = tdepthbits; glConfig.stencilBits = tstencilbits; break; } if ( !visinfo ) { ri.Printf( PRINT_ALL, "Couldn't get a visual\n" ); return RSERR_INVALID_MODE; } /* window attributes */ attr.background_pixel = BlackPixel( dpy, scrnum ); attr.border_pixel = 0; attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone ); attr.event_mask = X_MASK; if ( vidmode_active ) { mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore | CWEventMask | CWOverrideRedirect; attr.override_redirect = True; attr.backing_store = NotUseful; attr.save_under = False; } else { mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; } win = XCreateWindow( dpy, root, 0, 0, actualWidth, actualHeight, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr ); XStoreName( dpy, win, WINDOW_CLASS_NAME ); /* GH: Don't let the window be resized */ sizehints.flags = PMinSize | PMaxSize; sizehints.min_width = sizehints.max_width = actualWidth; sizehints.min_height = sizehints.max_height = actualHeight; XSetWMNormalHints( dpy, win, &sizehints ); XMapWindow( dpy, win ); if ( vidmode_active ) { XMoveWindow( dpy, win, 0, 0 ); } XFlush( dpy ); XSync( dpy,False ); // bk001130 - from cvs1.17 (mkv) ctx = qglXCreateContext( dpy, visinfo, NULL, True ); XSync( dpy,False ); // bk001130 - from cvs1.17 (mkv) /* GH: Free the visinfo after we're done with it */ XFree( visinfo ); qglXMakeCurrent( dpy, win, ctx ); // bk001130 - from cvs1.17 (mkv) glstring = qglGetString( GL_RENDERER ); ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glstring ); // bk010122 - new software token (Indirect) if ( !Q_stricmp( glstring, "Mesa X11" ) || !Q_stricmp( glstring, "Mesa GLX Indirect" ) ) { if ( !r_allowSoftwareGL->integer ) { ri.Printf( PRINT_ALL, "\n\n***********************************************************\n" ); ri.Printf( PRINT_ALL, " You are using software Mesa (no hardware acceleration)! \n" ); ri.Printf( PRINT_ALL, " Driver DLL used: %s\n", drivername ); ri.Printf( PRINT_ALL, " If this is intentional, add\n" ); ri.Printf( PRINT_ALL, " \"+set r_allowSoftwareGL 1\"\n" ); ri.Printf( PRINT_ALL, " to the command line when starting the game.\n" ); ri.Printf( PRINT_ALL, "***********************************************************\n" ); GLimp_Shutdown(); return RSERR_INVALID_MODE; } else { ri.Printf( PRINT_ALL, "...using software Mesa (r_allowSoftwareGL==1).\n" ); } } return RSERR_OK; }
GHOST_TSuccess GHOST_DisplayManagerX11:: setCurrentDisplaySetting( GHOST_TUns8 /*display*/, const GHOST_DisplaySetting& setting) { #ifdef WITH_X11_XF86VMODE /* Mode switching code ported from SDL: * See: src/video/x11/SDL_x11modes.c:set_best_resolution */ int majorVersion, minorVersion; XF86VidModeModeInfo **vidmodes; Display *dpy = m_system->getXDisplay(); int scrnum, num_vidmodes; if (dpy == NULL) return GHOST_kFailure; scrnum = DefaultScreen(dpy); /* Get video mode list */ majorVersion = minorVersion = 0; if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) { fprintf(stderr, "Error: XF86VidMode extension missing!\n"); return GHOST_kFailure; } # ifdef DEBUG printf("Using XFree86-VidModeExtension Version %d.%d\n", majorVersion, minorVersion); # endif if (XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes)) { int best_fit = -1; for (int i = 0; i < num_vidmodes; i++) { if (vidmodes[i]->hdisplay < setting.xPixels || vidmodes[i]->vdisplay < setting.yPixels) { continue; } if (best_fit == -1 || (vidmodes[i]->hdisplay < vidmodes[best_fit]->hdisplay) || (vidmodes[i]->hdisplay == vidmodes[best_fit]->hdisplay && vidmodes[i]->vdisplay < vidmodes[best_fit]->vdisplay)) { best_fit = i; continue; } if ((vidmodes[i]->hdisplay == vidmodes[best_fit]->hdisplay) && (vidmodes[i]->vdisplay == vidmodes[best_fit]->vdisplay)) { if (!setting.frequency) { /* Higher is better, right? */ if (calculate_rate(vidmodes[i]) > calculate_rate(vidmodes[best_fit])) { best_fit = i; } } else { if (abs(calculate_rate(vidmodes[i]) - (int)setting.frequency) < abs(calculate_rate(vidmodes[best_fit]) - (int)setting.frequency)) { best_fit = i; } } } } if (best_fit != -1) { # ifdef DEBUG printf("Switching to video mode %dx%d %dx%d %d\n", vidmodes[best_fit]->hdisplay, vidmodes[best_fit]->vdisplay, vidmodes[best_fit]->htotal, vidmodes[best_fit]->vtotal, calculate_rate(vidmodes[best_fit])); # endif /* change to the mode */ XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]); /* Move the viewport to top left */ XF86VidModeSetViewPort(dpy, scrnum, 0, 0); } XFree(vidmodes); } else { return GHOST_kFailure; } XFlush(dpy); return GHOST_kSuccess; #else /* Just pretend the request was successful. */ return GHOST_kSuccess; #endif }
static void xfvm_init(ALLEGRO_SYSTEM_XGLX *s) { int event_base = 0; int error_base = 0; /* init xfvm info to defaults */ s->xfvm_available = 0; s->xfvm_screen_count = 0; s->xfvm_screen = NULL; _al_mutex_lock(&s->lock); if (XF86VidModeQueryExtension(s->x11display, &event_base, &error_base)) { int minor_version = 0, major_version = 0; int status = XF86VidModeQueryVersion(s->x11display, &major_version, &minor_version); ALLEGRO_INFO("XF86VidMode version: %i.%i\n", major_version, minor_version); if (!status) { ALLEGRO_WARN("XF86VidMode not available, XF86VidModeQueryVersion failed.\n"); } else { // I don't actually know what versions are required here, just going to assume any is ok for now. ALLEGRO_INFO("XF86VidMode %i.%i is active\n", major_version, minor_version); s->xfvm_available = 1; } } else { ALLEGRO_WARN("XF86VidMode extension is not available.\n"); } if (s->xfvm_available) { int num_screens; #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA /* This is some fun stuff right here, if XRANDR is available, we can't use the xinerama screen count * and we really want the xrandr init in xglx_initialize to come last so it overrides xf86vm if available * and I really don't want to add more XRRQuery* or #ifdefs here. * I don't think XRandR can be disabled once its loaded, * so just seeing if its in the extension list should be fine. */ /* interesting thing to note is if XRandR is available, that means we have TwinView, * and not multi-head Xinerama mode, as True Xinerama disables XRandR on my NVidia. * which means all of those xfvm_screen_count != xinerama_screen_count tests * only apply to TwinView. As this code below sets xfvm_screen_count to xinerama_screen_count * making all those compares fail, and make us fall back to the normal xfvm multi-head code. */ /* second note, if FakeXinerama is disabled on TwinView setups, we will end up using * XRandR, as there is no other way to detect TwinView outside of libNVCtrl */ int ext_op, ext_evt, ext_err; Bool ext_ret = XQueryExtension(s->x11display, "RANDR", &ext_op, &ext_evt, &ext_err); if (s->xinerama_available && ext_ret == False) { num_screens = s->xinerama_screen_count; } else #endif { num_screens = ScreenCount(s->x11display); } ALLEGRO_DEBUG("XF86VidMode Got %d screens.\n", num_screens); s->xfvm_screen_count = num_screens; s->xfvm_screen = al_calloc(num_screens, sizeof(*s->xfvm_screen)); if (!s->xfvm_screen) { ALLEGRO_ERROR("XF86VidMode: failed to allocate screen array.\n"); s->xfvm_available = 0; } else { int i; for (i = 0; i < num_screens; i++) { ALLEGRO_DEBUG("XF86VidMode GetAllModeLines on screen %d.\n", i); if (!XF86VidModeGetAllModeLines(s->x11display, i, &(s->xfvm_screen[i].mode_count), &(s->xfvm_screen[i].modes))) { /* XXX what to do here? */ } } _al_xglx_mmon_interface.get_num_display_modes = xfvm_get_num_modes; _al_xglx_mmon_interface.get_display_mode = xfvm_get_mode; _al_xglx_mmon_interface.set_mode = xfvm_set_mode; _al_xglx_mmon_interface.store_mode = xfvm_store_video_mode; _al_xglx_mmon_interface.restore_mode = xfvm_restore_video_mode; _al_xglx_mmon_interface.get_display_offset = xfvm_get_display_offset; _al_xglx_mmon_interface.get_num_adapters = xfvm_get_num_adapters; _al_xglx_mmon_interface.get_monitor_info = xfvm_get_monitor_info; _al_xglx_mmon_interface.get_default_adapter = xfvm_get_default_adapter; _al_xglx_mmon_interface.get_xscreen = xfvm_get_xscreen; _al_xglx_mmon_interface.post_setup = xfvm_post_setup; } } _al_mutex_unlock(&s->lock); }
static void _VidModeQueryVersion(void) { int major, minor; XF86VidModeQueryVersion(g_Window.display, &major, &minor); printf("XF86VidModeQueryVersion %d.%d\n", major, minor); }
bool MWindow::create(const char * title, unsigned int width, unsigned int height, int colorBits, bool fullscreen) { static int dblBuf[] = {GLX_RGBA, GLX_RED_SIZE, 4, GLX_GREEN_SIZE, 4, GLX_BLUE_SIZE, 4, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None}; XVisualInfo * vi; Colormap cmap; XSetWindowAttributes swa; // open display display = XOpenDisplay(NULL); // fullscreen #ifndef __CYGWIN__ int vmMajor, vmMinor; if(XF86VidModeQueryVersion(display, &vmMajor, &vmMinor) && fullscreen) { screen = DefaultScreen(display); int modeNum, screenMode=0; XF86VidModeModeInfo **modes; XF86VidModeGetAllModeLines(display, screen, &modeNum, &modes); if(modeNum > 0) { desktopMode = *modes[0]; for(int i=0; i<modeNum; i++) { if((modes[i]->hdisplay == width) && (modes[i]->vdisplay == height)) screenMode = i; } XF86VidModeSwitchToMode(display, screen, modes[screenMode]); XF86VidModeSetViewPort(display, screen, 0, 0); m_width = modes[screenMode]->hdisplay; m_height = modes[screenMode]->vdisplay; XFree(modes); swa.override_redirect = True; swa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | ExposureMask | FocusChangeMask | VisibilityChangeMask; rootWindow = RootWindow(display,vi->screen); window = XCreateWindow( display, rootWindow, 0, 0, m_width, m_height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &swa); XWarpPointer(display, None, window, 0, 0, 0, 0, 0, 0); XMapRaised(display, window); XGrabKeyboard(display, window, True, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabPointer(display, window, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, window, None, CurrentTime); m_fullscreen = true; } else { return false; } } else #endif // window { m_fullscreen = false; vi = glXChooseVisual(display, DefaultScreen(display), dblBuf); context = glXCreateContext(display, vi, None, True); rootWindow = RootWindow(display,vi->screen); cmap = XCreateColormap(display,rootWindow,vi->visual,AllocNone); swa.colormap = cmap; swa.border_pixel = 0; swa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | ExposureMask | FocusChangeMask | VisibilityChangeMask; m_width = width; m_height = height; window = XCreateWindow( display, rootWindow, 0, 0, m_width, m_height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &swa); wmDelete = XInternAtom(display, "WM_DELETE_WINDOW", False); XSetWMProtocols(display, window, &wmDelete, 1); XSetStandardProperties(display, window, title, title, None, NULL, 0, NULL); XMapWindow(display, window); } // make current context glXMakeCurrent(display, window, context); // cursor nullCursor = createNULLCursor(display, rootWindow); return true; }
bool Game::setup(unsigned int GameSizeX, unsigned int GameSizeY, unsigned int BPP) { Globals::setGameData(this, GameSizeX, GameSizeY, BPP); State::bgColor = 0xff000000; #if defined(SDL_VIDEO) #ifdef DEBUG fprintf(stdout, "Initializing SDL Everything\n"); #endif if(SDL_Init(SDL_INIT_EVERYTHING) < 0) { _failtype = -1; fprintf(stderr, "Cannot initialize SDL\n"); return false; } #ifdef DEBUG fprintf(stdout, "Setup Game (W: %d H: %d BPP: %d) \n", GameSizeX, GameSizeY, BPP); #endif #if defined(SW_RENDER) _screen = SDL_SetVideoMode(Globals::width, Globals::height, BPP, SDL_SWSURFACE); #elif defined(HW_RENDER) #if defined(__APPLE__) #else _screen = SDL_SetVideoMode(Globals::width, Globals::height, BPP, SDL_OPENGL); #endif #endif if(!_screen) { _failtype = -1; fprintf(stderr, "Cannot initialize Video Mode\n"); return false; } if(TTF_WasInit() == 0) { #ifdef DEBUG fprintf(stdout, "Initializing SDL_TTF\n"); #endif if(TTF_Init() < 0) { _failtype = -1; fprintf(stderr, "Cannot initialize TTF system\n"); return false; } } SDL_WM_SetCaption(Globals::gameTitle.c_str(), NULL); atexit(SDL_Quit); atexit(TTF_Quit); #endif #if defined(X11_VIDEO) && defined(HW_RENDER) int attrListSgl[] = { GLX_RGBA, GLX_RED_SIZE, 4, GLX_GREEN_SIZE, 4, GLX_BLUE_SIZE, 4, GLX_DEPTH_SIZE, 16, None}; int attrListDbl[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 4, GLX_GREEN_SIZE, 4, GLX_BLUE_SIZE, 4, GLX_DEPTH_SIZE, 16, None}; XVisualInfo *vi; Colormap cmap; int dpyWidth, dpyHeight; int i; int vidModeMajorVersion, vidModeMinorVersion; XF86VidModeModeInfo **modes; int modeNum; int bestMode; Atom wmDelete; Window winDummy; unsigned int borderDummy; _GLWin.fs = false; bestMode = 0; _GLWin.dpy = XOpenDisplay(0); _GLWin.screen = DefaultScreen(_GLWin.dpy); XF86VidModeQueryVersion(_GLWin.dpy, &vidModeMajorVersion, &vidModeMinorVersion); XF86VidModeGetAllModeLines(_GLWin.dpy, _GLWin.screen, &modeNum, &modes); _GLWin.deskMode = *modes[0]; for (i = 0; i < modeNum; i++) { if ((modes[i]->hdisplay == GameSizeX) && (modes[i]->vdisplay == GameSizeY)) { bestMode = i; } } vi = glXChooseVisual(_GLWin.dpy, _GLWin.screen, attrListDbl); if(NULL == vi) { vi = glXChooseVisual(_GLWin.dpy, _GLWin.screen, attrListSgl); _GLWin.doublebuffer = false; } else { _GLWin.doublebuffer = true; } _GLWin.ctx = glXCreateContext(_GLWin.dpy, vi, 0, GL_TRUE); cmap = XCreateColormap(_GLWin.dpy, RootWindow(_GLWin.dpy, vi->screen),vi->visual, AllocNone); _GLWin.attr.colormap = cmap; _GLWin.attr.border_pixel = 0; if(_GLWin.fs) { XF86VidModeSwitchToMode(_GLWin.dpy, _GLWin.screen, modes[bestMode]); XF86VidModeSetViewPort(_GLWin.dpy, _GLWin.screen, 0, 0); dpyWidth = modes[bestMode]->hdisplay; dpyHeight = modes[bestMode]->vdisplay; XFree(modes); _GLWin.attr.override_redirect = True; _GLWin.attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | StructureNotifyMask; _GLWin.win = XCreateWindow(_GLWin.dpy, RootWindow(_GLWin.dpy, vi->screen), 0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &_GLWin.attr); XWarpPointer(_GLWin.dpy, None, _GLWin.win, 0, 0, 0, 0, 0, 0); XMapRaised(_GLWin.dpy, _GLWin.win); XGrabKeyboard(_GLWin.dpy, _GLWin.win, True, GrabModeAsync,GrabModeAsync, CurrentTime); XGrabPointer(_GLWin.dpy, _GLWin.win, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, _GLWin.win, None, CurrentTime); } else { _GLWin.attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask; _GLWin.win = XCreateWindow(_GLWin.dpy, RootWindow(_GLWin.dpy, vi->screen), 0, 0, GameSizeX, GameSizeY, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &_GLWin.attr); wmDelete = XInternAtom(_GLWin.dpy, "WM_DELETE_WINDOW", True); XSetWMProtocols(_GLWin.dpy, _GLWin.win, &wmDelete, 1); XSetStandardProperties(_GLWin.dpy, _GLWin.win, Globals::gameTitle.c_str(), Globals::gameTitle.c_str(), None, NULL, 0, NULL); XMapRaised(_GLWin.dpy, _GLWin.win); } glXMakeCurrent(_GLWin.dpy, _GLWin.win, _GLWin.ctx); XGetGeometry(_GLWin.dpy, _GLWin.win, &winDummy, &_GLWin.x, &_GLWin.y, &_GLWin.width, &_GLWin.height, &borderDummy, &_GLWin.bpp); XSetStandardProperties(_GLWin.dpy, _GLWin.win, Globals::gameTitle.c_str(), Globals::gameTitle.c_str(), None, NULL, 0, NULL); glFlush(); #endif #if defined(HW_RENDER) #if defined(VBO) #else glViewport(0, 0, Globals::width, Globals::height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, (GLfloat) Globals::width / (GLfloat) Globals::height, 0.1f, 100.0f); glMatrixMode(GL_MODELVIEW); glPushAttrib(GL_ENABLE_BIT); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glViewport(0, 0, Globals::width, Globals::height); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(0.0, (GLdouble)Globals::width,(GLdouble)Globals::height, 0.0, 0.0, 1.0); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); #endif #endif return true; }
/* ** GLW_SetMode */ int GLW_SetMode( const char *drivername, int mode, qboolean fullscreen ) { int attrib[] = { GLX_RGBA, // 0 GLX_RED_SIZE, 4, // 1, 2 GLX_GREEN_SIZE, 4, // 3, 4 GLX_BLUE_SIZE, 4, // 5, 6 GLX_DOUBLEBUFFER, // 7 GLX_DEPTH_SIZE, 1, // 8, 9 GLX_STENCIL_SIZE, 1, // 10, 11 None }; // these match in the array #define ATTR_RED_IDX 2 #define ATTR_GREEN_IDX 4 #define ATTR_BLUE_IDX 6 #define ATTR_DEPTH_IDX 9 #define ATTR_STENCIL_IDX 11 Window root; XVisualInfo *visinfo; XSetWindowAttributes attr; unsigned long mask; int colorbits, depthbits, stencilbits; int tcolorbits, tdepthbits, tstencilbits; int MajorVersion, MinorVersion; int actualWidth, actualHeight; int i; r_fakeFullscreen = ri.Cvar_Get( "r_fakeFullscreen", "0", CVAR_ARCHIVE); ri.Printf( PRINT_ALL, "Initializing OpenGL display\n"); ri.Printf (PRINT_ALL, "...setting mode %d:", mode ); if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) ) { ri.Printf( PRINT_ALL, " invalid mode\n" ); return RSERR_INVALID_MODE; } ri.Printf( PRINT_ALL, " %d %d\n", glConfig.vidWidth, glConfig.vidHeight); if (!(dpy = XOpenDisplay(NULL))) { fprintf(stderr, "Error couldn't open the X display\n"); return RSERR_INVALID_MODE; } scrnum = DefaultScreen(dpy); root = RootWindow(dpy, scrnum); actualWidth = glConfig.vidWidth; actualHeight = glConfig.vidHeight; // Get video mode list MajorVersion = MinorVersion = 0; if (!XF86VidModeQueryVersion(dpy, &MajorVersion, &MinorVersion)) { vidmode_ext = qfalse; } else { ri.Printf(PRINT_ALL, "Using XFree86-VidModeExtension Version %d.%d\n", MajorVersion, MinorVersion); vidmode_ext = qtrue; } if (vidmode_ext) { int best_fit, best_dist, dist, x, y; XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes); // Are we going fullscreen? If so, let's change video mode if (fullscreen && !r_fakeFullscreen->integer) { best_dist = 9999999; best_fit = -1; for (i = 0; i < num_vidmodes; i++) { if (glConfig.vidWidth > vidmodes[i]->hdisplay || glConfig.vidHeight > vidmodes[i]->vdisplay) continue; x = glConfig.vidWidth - vidmodes[i]->hdisplay; y = glConfig.vidHeight - vidmodes[i]->vdisplay; dist = (x * x) + (y * y); if (dist < best_dist) { best_dist = dist; best_fit = i; } } if (best_fit != -1) { actualWidth = vidmodes[best_fit]->hdisplay; actualHeight = vidmodes[best_fit]->vdisplay; // change to the mode XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]); vidmode_active = qtrue; // Move the viewport to top left XF86VidModeSetViewPort(dpy, scrnum, 0, 0); } else fullscreen = 0; } } if (!r_colorbits->value) colorbits = 24; else colorbits = r_colorbits->value; if ( !Q_stricmp( r_glDriver->string, _3DFX_DRIVER_NAME ) ) colorbits = 16; if (!r_depthbits->value) depthbits = 24; else depthbits = r_depthbits->value; stencilbits = r_stencilbits->value; for (i = 0; i < 16; i++) { // 0 - default // 1 - minus colorbits // 2 - minus depthbits // 3 - minus stencil if ((i % 4) == 0 && i) { // one pass, reduce switch (i / 4) { case 2 : if (colorbits == 24) colorbits = 16; break; case 1 : if (depthbits == 24) depthbits = 16; else if (depthbits == 16) depthbits = 8; case 3 : if (stencilbits == 24) stencilbits = 16; else if (stencilbits == 16) stencilbits = 8; } } tcolorbits = colorbits; tdepthbits = depthbits; tstencilbits = stencilbits; if ((i % 4) == 3) { // reduce colorbits if (tcolorbits == 24) tcolorbits = 16; } if ((i % 4) == 2) { // reduce depthbits if (tdepthbits == 24) tdepthbits = 16; else if (tdepthbits == 16) tdepthbits = 8; } if ((i % 4) == 1) { // reduce stencilbits if (tstencilbits == 24) tstencilbits = 16; else if (tstencilbits == 16) tstencilbits = 8; else tstencilbits = 0; } if (tcolorbits == 24) { attrib[ATTR_RED_IDX] = 8; attrib[ATTR_GREEN_IDX] = 8; attrib[ATTR_BLUE_IDX] = 8; } else { // must be 16 bit attrib[ATTR_RED_IDX] = 4; attrib[ATTR_GREEN_IDX] = 4; attrib[ATTR_BLUE_IDX] = 4; } attrib[ATTR_DEPTH_IDX] = tdepthbits; // default to 24 depth attrib[ATTR_STENCIL_IDX] = tstencilbits; #if 0 ri.Printf( PRINT_DEVELOPER, "Attempting %d/%d/%d Color bits, %d depth, %d stencil display...", attrib[ATTR_RED_IDX], attrib[ATTR_GREEN_IDX], attrib[ATTR_BLUE_IDX], attrib[ATTR_DEPTH_IDX], attrib[ATTR_STENCIL_IDX]); #endif visinfo = qglXChooseVisual(dpy, scrnum, attrib); if (!visinfo) { #if 0 ri.Printf( PRINT_DEVELOPER, "failed\n"); #endif continue; } #if 0 ri.Printf( PRINT_DEVELOPER, "Successful\n"); #endif ri.Printf( PRINT_ALL, "Using %d/%d/%d Color bits, %d depth, %d stencil display.\n", attrib[ATTR_RED_IDX], attrib[ATTR_GREEN_IDX], attrib[ATTR_BLUE_IDX], attrib[ATTR_DEPTH_IDX], attrib[ATTR_STENCIL_IDX]); glConfig.colorBits = tcolorbits; glConfig.depthBits = tdepthbits; glConfig.stencilBits = tstencilbits; break; } if (!visinfo) { ri.Printf( PRINT_ALL, "Couldn't get a visual\n" ); return RSERR_INVALID_MODE; } /* window attributes */ attr.background_pixel = BlackPixel(dpy, scrnum); attr.border_pixel = 0; attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone); attr.event_mask = X_MASK; if (vidmode_active) { mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore | CWEventMask | CWOverrideRedirect; attr.override_redirect = True; attr.backing_store = NotUseful; attr.save_under = False; } else mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; win = XCreateWindow(dpy, root, 0, 0, actualWidth, actualHeight, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr); XMapWindow(dpy, win); if (vidmode_active) XMoveWindow(dpy, win, 0, 0); // Check for DGA if (in_dgamouse->value) { if (!XF86DGAQueryVersion(dpy, &MajorVersion, &MinorVersion)) { // unable to query, probalby not supported ri.Printf( PRINT_ALL, "Failed to detect XF86DGA Mouse\n" ); ri.Cvar_Set( "in_dgamouse", "0" ); } else ri.Printf( PRINT_ALL, "XF86DGA Mouse (Version %d.%d) initialized\n", MajorVersion, MinorVersion); } XFlush(dpy); ctx = qglXCreateContext(dpy, visinfo, NULL, True); qglXMakeCurrent(dpy, win, ctx); return RSERR_OK; }
void createWindow(int setWidth, int setHeight) { width = setWidth; height = setHeight; XVisualInfo *vi; Colormap cmap; int i, dpyWidth, dpyHeight; int glxMajor, glxMinor, vmMajor, vmMinor; XF86VidModeModeInfo **modes; int modeNum, bestMode; Atom wmDelete; // set best mode to current bestMode = 0; // get a connection display = XOpenDisplay(0); screen = DefaultScreen(display); XF86VidModeQueryVersion(display, &vmMajor, &vmMinor); cout << "XF86 VideoMode extension version " << vmMajor << "." << vmMinor << endl; XF86VidModeGetAllModeLines(display, screen, &modeNum, &modes); // save desktop-resolution before switching modes GLWin.deskMode = *modes[0]; desktopMode = *modes[0]; // look for mode with requested resolution for (i = 0; i < modeNum; i++) { if ((modes[i]->hdisplay == width) && (modes[i]->vdisplay == height)) bestMode = i; } // get an appropriate visual vi = glXChooseVisual(display, screen, attrListDbl); if (vi == NULL) { vi = glXChooseVisual(display, screen, attrListSgl); doubleBuffered = False; cout << "singlebuffered rendering will be used, no doublebuffering available" << endl; } else { doubleBuffered = True; cout << "doublebuffered rendering available" << endl; } glXQueryVersion(display, &glxMajor, &glxMinor); cout << "GLX-Version " << glxMajor << "." << glxMinor << endl; // create a GLX context glxContext = glXCreateContext(display, vi, 0, GL_TRUE); // create a color map cmap = XCreateColormap(display, RootWindow(display, vi->screen), vi->visual, AllocNone); winAttr.colormap = cmap; winAttr.border_pixel = 0; if (fullscreen) { // switch to fullscreen XF86VidModeSwitchToMode(display, screen, modes[bestMode]); XF86VidModeSetViewPort(display, screen, 0, 0); dpyWidth = modes[bestMode]->hdisplay; dpyHeight = modes[bestMode]->vdisplay; cout << "resolution " << dpyWidth << "x" << dpyHeight << endl; XFree(modes); // set window attributes winAttr.override_redirect = True; winAttr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask; window = XCreateWindow(display, RootWindow(display, vi->screen), 0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &winAttr); XWarpPointer(display, None, window, 0, 0, 0, 0, 0, 0); XMapRaised(display, window); XGrabKeyboard(display, window, True, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabPointer(display, window, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, window, None, CurrentTime); } else { // create a window in window mode winAttr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask | ButtonReleaseMask | PointerMotionMask; window = XCreateWindow(display, RootWindow(display, vi->screen), 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &winAttr); // only set window title and handle wm_delete_events if in windowed mode wmDelete = XInternAtom(display, "WM_DELETE_WINDOW", True); XSetWMProtocols(display, window, &wmDelete, 1); XSetStandardProperties(display, window, title.c_str(), title.c_str(), None, NULL, 0, NULL); XMapRaised(display, window); } // connect the glx-context to the window glXMakeCurrent(display, window, glxContext); if (glXIsDirect(display, glxContext)) cout << "DRI enabled" << endl; else cout << "no DRI available" << endl; }
/* * Implementation */ Bool VideoModeInitialize(void) { Widget form; char dispstr[128], *ptr, *tmp; static char *names[] = { NULL, NULL, "hsyncstart", "hsyncend", "htotal", "vsyncstart", "vsyncend", "vtotal", "flags", "clock", "hsync", "vsync", }; static char *vnames[] = { NULL, NULL, "v-hsyncstart", "v-hsyncend", "v-htotal", "v-vsyncstart", "v-vsyncend", "v-vtotal", "v-flags", "v-clock", "v-hsync", "v-vsync", }; Widget rep; int i; if (!XF86VidModeQueryVersion(XtDisplay(toplevel), &MajorVersion, &MinorVersion)) { fprintf(stderr, "Unable to query video extension version\n"); return (False); } else if (!XF86VidModeQueryExtension(XtDisplay(toplevel), &EventBase, &ErrorBase)) { fprintf(stderr, "Unable to query video extension information\n"); return (False); } else if (MajorVersion < MINMAJOR || (MajorVersion == MINMAJOR && MinorVersion < MINMINOR)) { fprintf(stderr, "Xserver is running an old XFree86-VidModeExtension version" " (%d.%d)\n", MajorVersion, MinorVersion); fprintf(stderr, "Minimum required version is %d.%d\n", MINMAJOR, MINMINOR); return (False); } else InitializeVidmodes(); vtune = XtCreateWidget("vidtune", formWidgetClass, work, NULL, 0); (void) XtVaCreateManagedWidget("vesaB", menuButtonWidgetClass, vtune, XtNmenuName, "vesaP", NULL, 0); vesap = XtCreatePopupShell("vesaP", simpleMenuWidgetClass, vtune, NULL, 0); for (i = 0; i < sizeof(vesamodes) / sizeof(vesamodes[0]); i++) { rep = XtCreateManagedWidget(vesamodes[i].ident, smeBSBObjectClass, vesap, NULL, 0); XtAddCallback(rep, XtNcallback, AddVesaModeCallback, (XtPointer)&vesamodes[i]); } rep = XtCreateManagedWidget("prev", commandWidgetClass, vtune, NULL, 0); XtAddCallback(rep, XtNcallback, SwitchCallback, (XtPointer)-1); mode = XtCreateManagedWidget("mode", menuButtonWidgetClass, vtune, NULL, 0); rep = XtCreateManagedWidget("next", commandWidgetClass, vtune, NULL, 0); XtAddCallback(rep, XtNcallback, SwitchCallback, (XtPointer)1); screenp = XtCreatePopupShell("screenP", simpleMenuWidgetClass, vtune, NULL, 0); XmuSnprintf(dispstr, sizeof(dispstr), "%s", DisplayString(XtDisplay(toplevel))); ptr = strrchr(dispstr, '.'); tmp = strrchr(dispstr, ':'); if (tmp != NULL && ptr != NULL && ptr > tmp) *ptr = '\0'; for (i = 0; i < ScreenCount(XtDisplay(toplevel)); i++) { char name[128]; XmuSnprintf(name, sizeof(name), "%s.%d", dispstr, i); rep = XtCreateManagedWidget(name, smeBSBObjectClass, screenp, NULL, 0); XtAddCallback(rep, XtNcallback, ChangeScreenCallback, (XtPointer)(long)i); if (i == 0) { screenb = XtVaCreateManagedWidget("screenB", menuButtonWidgetClass, vtune, XtNmenuName, "screenP", XtNlabel, name, NULL, 0); } } XtRealizeWidget(screenp); rep = XtCreateManagedWidget("up", repeaterWidgetClass, vtune, NULL, 0); XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL); XtAddCallback(rep, XtNcallback, AdjustMonitorCallback, (XtPointer)UP); XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL); rep = XtCreateManagedWidget("left", repeaterWidgetClass, vtune, NULL, 0); XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL); XtAddCallback(rep, XtNcallback, AdjustMonitorCallback, (XtPointer)LEFT); XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL); XtCreateManagedWidget("monitor", simpleWidgetClass, vtune, NULL, 0); rep = XtCreateManagedWidget("right", repeaterWidgetClass, vtune, NULL, 0); XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL); XtAddCallback(rep, XtNcallback, AdjustMonitorCallback, (XtPointer)RIGHT); XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL); rep = XtCreateManagedWidget("down", repeaterWidgetClass, vtune, NULL, 0); XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL); XtAddCallback(rep, XtNcallback, AdjustMonitorCallback, (XtPointer)DOWN); XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL); rep = XtCreateManagedWidget("wider", repeaterWidgetClass, vtune, NULL, 0); XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL); XtAddCallback(rep, XtNcallback, AdjustMonitorCallback, (XtPointer)WIDER); XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL); rep = XtCreateManagedWidget("narrower", repeaterWidgetClass, vtune, NULL, 0); XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL); XtAddCallback(rep, XtNcallback, AdjustMonitorCallback, (XtPointer)NARROWER); XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL); rep = XtCreateManagedWidget("shorter", repeaterWidgetClass, vtune, NULL, 0); XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL); XtAddCallback(rep, XtNcallback, AdjustMonitorCallback, (XtPointer)SHORTER); XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL); rep = XtCreateManagedWidget("taller", repeaterWidgetClass, vtune, NULL, 0); XtAddCallback(rep, XtNstartCallback, StartAdjustMonitorCallback, NULL); XtAddCallback(rep, XtNcallback, AdjustMonitorCallback, (XtPointer)TALLER); XtAddCallback(rep, XtNstopCallback, EndAdjustMonitorCallback, NULL); automatic = XtCreateManagedWidget("auto", toggleWidgetClass, vtune, NULL, 0); XtAddCallback(automatic, XtNcallback, AutoCallback, NULL); apply = XtCreateManagedWidget("apply", commandWidgetClass, vtune, NULL, 0); XtAddCallback(apply, XtNcallback, ApplyCallback, NULL); restore = XtCreateManagedWidget("restore", commandWidgetClass, vtune, NULL, 0); XtAddCallback(restore, XtNcallback, RestoreCallback, NULL); rep = XtCreateManagedWidget("update", commandWidgetClass, vtune, NULL, 0); XtAddCallback(rep, XtNcallback, UpdateCallback, NULL); rep = XtCreateManagedWidget("test", commandWidgetClass, vtune, NULL, 0); XtAddCallback(rep, XtNcallback, TestCallback, NULL); form = XtCreateManagedWidget("form", formWidgetClass, vtune, NULL, 0); for (i = 2; i < VSYNC + 1; i++) { (void) XtCreateManagedWidget(names[i], labelWidgetClass, form, NULL, 0); values[i] = XtCreateManagedWidget(vnames[i], labelWidgetClass, form, NULL, 0); } add = XtCreateManagedWidget("add", commandWidgetClass, vtune, NULL, 0); XtAddCallback(add, XtNcallback, AddModeCallback, NULL); XtCreateManagedWidget("addto", labelWidgetClass, vtune, NULL, 0); monitorb = XtCreateManagedWidget("ident", menuButtonWidgetClass, vtune, NULL, 0); XtCreateManagedWidget("as", labelWidgetClass, vtune, NULL, 0); text = XtVaCreateManagedWidget("text", asciiTextWidgetClass, vtune, XtNeditType, XawtextEdit, NULL, 0); XtRealizeWidget(vtune); return (True); }
GLWindow::GLWindow(const char * title, int width, int height, int bits, bool fullscreen, WNDPROC wndproc) { #ifdef _WIN32 GLuint PixelFormat; // Holds The Results After Searching For A Match WNDCLASS wc; // Windows Class Structure DWORD dwExStyle; // Window Extended Style DWORD dwStyle; // Window Style RECT WindowRect; // Grabs Rectangle Upper Left / Lower Right Values WindowRect.left = (long) 0; // Set Left Value To 0 WindowRect.right =(long) width; // Set Right Value To Requested Width WindowRect.top = (long) 0; // Set Top Value To 0 WindowRect.bottom = (long) height; // Set Bottom Value To Requested Height bool result = true; mInitialized = false; if(result) { mhInstance = GetModuleHandle(NULL); wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wc.lpfnWndProc = (WNDPROC) wndproc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = mhInstance; wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = NULL; wc.lpszMenuName = NULL; wc.lpszClassName = "OpenGL"; } if(result) { if(!RegisterClass(&wc)) { result = false; } } if(result) { DEVMODE dmScreenSettings; memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); dmScreenSettings.dmSize=sizeof(dmScreenSettings); dmScreenSettings.dmPelsWidth = width; dmScreenSettings.dmPelsHeight = height; dmScreenSettings.dmBitsPerPel = bits; dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; if(fullscreen) { ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN); dwExStyle = WS_EX_APPWINDOW; dwStyle = WS_POPUP; } else { dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; dwStyle = WS_OVERLAPPEDWINDOW; } AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); } if(result) { dwStyle |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN; mhWnd = CreateWindowEx(dwExStyle, "OpenGL", title, dwStyle, 0, 0, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top, NULL, NULL, mhInstance, NULL); if(!mhWnd) { free(); result = false; } } if(result) { mhDC = GetDC(mhWnd); if(!mhDC) { free(); result = false; } } static PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, bits, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 }; if(result) { PixelFormat = ChoosePixelFormat(mhDC, &pfd); if(!PixelFormat) { free(); result = false; } } if(result) { if(!SetPixelFormat(mhDC, PixelFormat, &pfd)) { free(); result = false; } } if(result) { mhRC = wglCreateContext(mhDC); if(!mhRC) { free(); result = false; } } if(result) { if(!wglMakeCurrent(mhDC, mhRC)) { free(); result = false; } } if(result) { ShowCursor(FALSE); ShowWindow(mhWnd, SW_SHOW); SetForegroundWindow(mhWnd); SetFocus(mhWnd); } if(result) { if(!initOpenGL()) { free(); result = false; } } mInitialized = result; #else XVisualInfo *vi; Colormap cmap; int i, dpyWidth, dpyHeight; int glxMajor, glxMinor, vmMajor, vmMinor; XF86VidModeModeInfo **modes; int modeNum, bestMode; Atom wmDelete; Window winDummy; unsigned int borderDummy; mFullscreen = fullscreen; /* set best mode to current */ bestMode = 0; /* get a connection */ mDisplay = XOpenDisplay(0); mScreen = DefaultScreen(mDisplay); XF86VidModeQueryVersion(mDisplay, &vmMajor, &vmMinor); XF86VidModeGetAllModeLines(mDisplay, mScreen, &modeNum, &modes); /* save desktop-resolution before switching modes */ mDeskMode = *modes[0]; /* look for mode with requested resolution */ for (i = 0; i < modeNum; i++) { if ((modes[i]->hdisplay == width) && (modes[i]->vdisplay == height)) bestMode = i; } /* get an appropriate visual */ vi = glXChooseVisual(mDisplay, mScreen, attrListDbl); if (vi == NULL) { vi = glXChooseVisual(mDisplay, mScreen, attrListSgl); mDoubleBuffered = False; } else { mDoubleBuffered = True; } glXQueryVersion(mDisplay, &glxMajor, &glxMinor); Debug::Log("GLX-Version %d.%d\n", glxMajor, glxMinor); /* create a GLX context */ mCtx = glXCreateContext(mDisplay, vi, 0, GL_TRUE); /* create a color map */ cmap = XCreateColormap(mDisplay, RootWindow(mDisplay, vi->screen), vi->visual, AllocNone); mWinAttr.colormap = cmap; mWinAttr.border_pixel = 0; if(fullscreen) { /* switch to fullscreen */ XF86VidModeSwitchToMode(mDisplay, mScreen, modes[bestMode]); XF86VidModeSetViewPort(mDisplay, mScreen, 0, 0); dpyWidth = modes[bestMode]->hdisplay; dpyHeight = modes[bestMode]->vdisplay; XFree(modes); /* set window attributes */ mWinAttr.override_redirect = True; mWinAttr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | StructureNotifyMask; mWindow = XCreateWindow(mDisplay, RootWindow(mDisplay, vi->screen), 0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &mWinAttr); XWarpPointer(mDisplay, None, mWindow, 0, 0, 0, 0, 0, 0); XMapRaised(mDisplay, mWindow); XGrabKeyboard(mDisplay, mWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabPointer(mDisplay, mWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, mWindow, None, CurrentTime); } else { /* create a window in window mode*/ mWinAttr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | StructureNotifyMask; mWindow = XCreateWindow(mDisplay, RootWindow(mDisplay, vi->screen), 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &mWinAttr); /* only set window title and handle wm_delete_events if in windowed mode */ wmDelete = XInternAtom(mDisplay, "WM_DELETE_WINDOW", True); XSetWMProtocols(mDisplay, mWindow, &wmDelete, 1); XSetStandardProperties(mDisplay, mWindow, title, title, None, NULL, 0, NULL); XMapRaised(mDisplay, mWindow); } /* connect the glx-context to the window */ glXMakeCurrent(mDisplay, mWindow, mCtx); initOpenGL(); mInitialized = true; #endif }
/* FIXME: bits is currently unused */ GLWindow * createGLWindow(struct display_camera *camera) { GLWindow *x11_gl_window = New( GLWindow ); XVisualInfo *vi; Colormap cmap; int dpyWidth, dpyHeight; int i; int glxMajorVersion, glxMinorVersion; int vidModeMajorVersion, vidModeMinorVersion; XF86VidModeModeInfo **modes; int modeNum; int bestMode; Atom wmDelete; Window winDummy; unsigned int borderDummy; MemSet( x11_gl_window, 0, sizeof( GLWindow ) ); camera->hVidCore->x11_gl_window = x11_gl_window; x11_gl_window->fs = 0;//fullscreenflag; /* set best mode to current */ bestMode = 0; /* get a connection */ x11_gl_window->dpy = XOpenDisplay(0); if( x11_gl_window->dpy ) { x11_gl_window->screen = DefaultScreen(x11_gl_window->dpy); #if 0 x11_gl_window->atom_create = XInternAtom( x11_gl_window->dpy, "UserCreateWindow", 0 ); XF86VidModeQueryVersion(x11_gl_window->dpy, &vidModeMajorVersion, &vidModeMinorVersion); printf("XF86VidModeExtension-Version %d.%d\n", vidModeMajorVersion, vidModeMinorVersion); if( x11_gl_window->fs ) { XF86VidModeGetAllModeLines(x11_gl_window->dpy, x11_gl_window->screen, &modeNum, &modes); /* save desktop-resolution before switching modes */ x11_gl_window->deskMode = *modes[0]; /* look for mode with requested resolution */ for (i = 0; i < modeNum; i++) { if ((modes[i]->hdisplay == camera->w) && (modes[i]->vdisplay == camera->h)) { bestMode = i; } } } #endif /* get an appropriate visual */ vi = glXChooseVisual(x11_gl_window->dpy, x11_gl_window->screen, attrListDbl); if (vi == NULL) { vi = glXChooseVisual(x11_gl_window->dpy, x11_gl_window->screen, attrListSgl); x11_gl_window->doubleBuffered = False; printf("Only Singlebuffered Visual!\n"); } else { x11_gl_window->doubleBuffered = True; printf("Got Doublebuffered Visual!\n"); } glXQueryVersion(x11_gl_window->dpy, &glxMajorVersion, &glxMinorVersion); printf("glX-Version %d.%d\n", glxMajorVersion, glxMinorVersion); /* create a GLX context */ x11_gl_window->ctx = glXCreateContext(x11_gl_window->dpy, vi, 0, GL_TRUE); /* create a color map */ lprintf( "colormap..." ); cmap = XCreateColormap(x11_gl_window->dpy, RootWindow(x11_gl_window->dpy, vi->screen), vi->visual, AllocNone); x11_gl_window->attr.colormap = cmap; x11_gl_window->attr.border_pixel = 0; x11_gl_window->attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | PointerMotionMask | StructureNotifyMask; if (x11_gl_window->fs) { XF86VidModeSwitchToMode(x11_gl_window->dpy, x11_gl_window->screen, modes[bestMode]); XF86VidModeSetViewPort(x11_gl_window->dpy, x11_gl_window->screen, 0, 0); dpyWidth = modes[bestMode]->hdisplay; dpyHeight = modes[bestMode]->vdisplay; printf("Resolution %dx%d\n", dpyWidth, dpyHeight); XFree(modes); /* create a fullscreen window */ x11_gl_window->attr.override_redirect = True; x11_gl_window->win = XCreateWindow(x11_gl_window->dpy, RootWindow(x11_gl_window->dpy, vi->screen), 0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &x11_gl_window->attr); XWarpPointer(x11_gl_window->dpy, None, x11_gl_window->win, 0, 0, 0, 0, 0, 0); XMapRaised(x11_gl_window->dpy, x11_gl_window->win); XGrabKeyboard(x11_gl_window->dpy, x11_gl_window->win, True, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabPointer(x11_gl_window->dpy, x11_gl_window->win, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, x11_gl_window->win, None, CurrentTime); } else { /* create a window in window mode*/ lprintf( "create window... %d,%d %d", camera->w, camera->h, vi->depth ); x11_gl_window->win = XCreateWindow(x11_gl_window->dpy, RootWindow(x11_gl_window->dpy, vi->screen), 0, 0, camera->w, camera->h, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &x11_gl_window->attr); /* only set window title and handle wm_delete_events if in windowed mode */ wmDelete = XInternAtom(x11_gl_window->dpy, "WM_DELETE_WINDOW", True); XSetWMProtocols(x11_gl_window->dpy, x11_gl_window->win, &wmDelete, 1); XSetStandardProperties(x11_gl_window->dpy, x11_gl_window->win, "No Title", "No Title", None, NULL, 0, NULL); XMapRaised(x11_gl_window->dpy, x11_gl_window->win); } /* connect the glx-context to the window */ SetActiveGLDisplayView( camera, 0 ); //glXMakeCurrent(x11_gl_window->dpy, x11_gl_window->win, x11_gl_window->ctx); XGetGeometry(x11_gl_window->dpy, x11_gl_window->win, &winDummy, &x11_gl_window->x, &x11_gl_window->y, &x11_gl_window->width, &x11_gl_window->height, &borderDummy, &x11_gl_window->depth); printf("Depth %d\n", x11_gl_window->depth); if (glXIsDirect(x11_gl_window->dpy, x11_gl_window->ctx)) printf("Congrats, you have Direct Rendering!\n"); else printf("Sorry, no Direct Rendering possible!\n"); } else { lprintf( "Failed to open display" ); return NULL; } return x11_gl_window; }
/* ** GLW_SetMode */ int GLW_SetMode( const char *drivername, int mode, qboolean fullscreen ) { #ifdef HAVE_GLES glConfig.vidWidth = 800; glConfig.vidHeight = 480; // glConfig.windowAspect = 800.0 / 480.0; long event_mask=X_MASK; dpy = XOpenDisplay(0); if(!dpy) { ri.Printf( PRINT_ALL, "couldn't open display\n"); return qfalse; } scrnum = DefaultScreen(dpy); ri.Printf( PRINT_ALL, "using default screen %d\n", scrnum); ri.Printf( PRINT_ALL, "setting up EGL window\n"); XSetWindowAttributes attr = { 0 }; attr.event_mask = event_mask; // attr.colormap = colormap; attr.override_redirect = qtrue; win = XCreateWindow(dpy, RootWindow(dpy, scrnum), 0, 0, glConfig.vidWidth, glConfig.vidHeight, 0, CopyFromParent, InputOutput, CopyFromParent, CWEventMask, &attr); if(!win) { return qfalse; } Atom wmState = XInternAtom(dpy, "_NET_WM_STATE", False); Atom wmFullscreen = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); XChangeProperty(dpy, win, wmState, XA_ATOM, 32, PropModeReplace, (unsigned char *)&wmFullscreen, 1); XMapRaised(dpy, win); g_EGLWindow = (NativeWindowType)win; #ifdef PANDORA g_EGLDisplay = eglGetDisplay((EGLNativeDisplayType)EGL_DEFAULT_DISPLAY); #else g_EGLDisplay = eglGetDisplay((EGLNativeDisplayType)dpy); #endif if(g_EGLDisplay == EGL_NO_DISPLAY) { ri.Printf( PRINT_ALL, "error getting EGL display\n"); return qfalse; } if(!eglInitialize(g_EGLDisplay, NULL, NULL)) { ri.Printf( PRINT_ALL, "error initializing EGL"); return 0; } const EGLint attribs[] = { EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_ALPHA_SIZE, 0, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT, EGL_DEPTH_SIZE, 16, EGL_NONE, 0, }; EGLint configs = 0; eglChooseConfig(g_EGLDisplay, attribs, &g_EGLConfig, 1, &configs); if(!configs) { static const EGLint eglAttrWinLowColor[] = { EGL_NONE }; ri.Printf( PRINT_ALL, "falling back to lowest color config\n"); eglChooseConfig(g_EGLDisplay, eglAttrWinLowColor, &g_EGLConfig, 1, &configs); if(!configs) { ri.Printf( PRINT_ALL, "no valid EGL configs found\n"); return qfalse; } } #ifdef PANDORA g_EGLWindowSurface = eglCreateWindowSurface(g_EGLDisplay, g_EGLConfig, NULL, NULL); #else g_EGLWindowSurface = eglCreateWindowSurface(g_EGLDisplay, g_EGLConfig, g_EGLWindow, NULL); #endif if(g_EGLWindowSurface == EGL_NO_SURFACE) { ri.Printf( PRINT_ALL, "error creating window surface: 0x%X\n", (int)eglGetError()); return qfalse; } EGLint ctxAttr[] = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE }; g_EGLContext = eglCreateContext(g_EGLDisplay, g_EGLConfig, EGL_NO_CONTEXT, ctxAttr); if(g_EGLContext == EGL_NO_CONTEXT) { ri.Printf( PRINT_ALL, "error creating context: 0x%X\n", (int)eglGetError()); return qfalse; } eglMakeCurrent(g_EGLDisplay, g_EGLWindowSurface, g_EGLWindowSurface, g_EGLContext); { EGLint width, height, color, depth, stencil; eglQuerySurface(g_EGLDisplay, g_EGLWindowSurface, EGL_WIDTH, &width); eglQuerySurface(g_EGLDisplay, g_EGLWindowSurface, EGL_HEIGHT, &height); ri.Printf(PRINT_ALL, "Window size: %dx%d\n", width, height); eglGetConfigAttrib(g_EGLDisplay, g_EGLConfig, EGL_BUFFER_SIZE, &color); eglGetConfigAttrib(g_EGLDisplay, g_EGLConfig, EGL_DEPTH_SIZE, &depth); eglGetConfigAttrib(g_EGLDisplay, g_EGLConfig, EGL_STENCIL_SIZE, &stencil); /* glConfig.vidWidth = width; glConfig.vidHeight = height;*/ glConfig.colorBits = color; glConfig.depthBits = depth; glConfig.stencilBits = stencil; } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); #else int attrib[] = { GLX_RGBA, // 0 GLX_RED_SIZE, 4, // 1, 2 GLX_GREEN_SIZE, 4, // 3, 4 GLX_BLUE_SIZE, 4, // 5, 6 GLX_DOUBLEBUFFER, // 7 GLX_DEPTH_SIZE, 1, // 8, 9 GLX_STENCIL_SIZE, 1, // 10, 11 None }; // these match in the array #define ATTR_RED_IDX 2 #define ATTR_GREEN_IDX 4 #define ATTR_BLUE_IDX 6 #define ATTR_DEPTH_IDX 9 #define ATTR_STENCIL_IDX 11 Window root; XVisualInfo *visinfo; XSetWindowAttributes attr; unsigned long mask; int colorbits, depthbits, stencilbits; int tcolorbits, tdepthbits, tstencilbits; int dga_MajorVersion, dga_MinorVersion; int actualWidth, actualHeight; int i; const char* glstring; // bk001130 - from cvs1.17 (mkv) ri.Printf( PRINT_ALL, "Initializing OpenGL display\n" ); ri.Printf( PRINT_ALL, "...setting mode %d:", mode ); if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) ) { ri.Printf( PRINT_ALL, " invalid mode\n" ); return RSERR_INVALID_MODE; } ri.Printf( PRINT_ALL, " %d %d\n", glConfig.vidWidth, glConfig.vidHeight ); if ( !( dpy = XOpenDisplay( NULL ) ) ) { fprintf( stderr, "Error couldn't open the X display\n" ); return RSERR_INVALID_MODE; } scrnum = DefaultScreen( dpy ); root = RootWindow( dpy, scrnum ); actualWidth = glConfig.vidWidth; actualHeight = glConfig.vidHeight; // Get video mode list if ( !XF86VidModeQueryVersion( dpy, &vidmode_MajorVersion, &vidmode_MinorVersion ) ) { vidmode_ext = qfalse; } else { ri.Printf( PRINT_ALL, "Using XFree86-VidModeExtension Version %d.%d\n", vidmode_MajorVersion, vidmode_MinorVersion ); vidmode_ext = qtrue; } // Check for DGA dga_MajorVersion = 0, dga_MinorVersion = 0; if ( in_dgamouse->value ) { if ( !XF86DGAQueryVersion( dpy, &dga_MajorVersion, &dga_MinorVersion ) ) { // unable to query, probalby not supported ri.Printf( PRINT_ALL, "Failed to detect XF86DGA Mouse\n" ); ri.Cvar_Set( "in_dgamouse", "0" ); } else { ri.Printf( PRINT_ALL, "XF86DGA Mouse (Version %d.%d) initialized\n", dga_MajorVersion, dga_MinorVersion ); } } if ( vidmode_ext ) { int best_fit, best_dist, dist, x, y; XF86VidModeGetAllModeLines( dpy, scrnum, &num_vidmodes, &vidmodes ); // Are we going fullscreen? If so, let's change video mode if ( fullscreen ) { best_dist = 9999999; best_fit = -1; for ( i = 0; i < num_vidmodes; i++ ) { if ( glConfig.vidWidth > vidmodes[i]->hdisplay || glConfig.vidHeight > vidmodes[i]->vdisplay ) { continue; } x = glConfig.vidWidth - vidmodes[i]->hdisplay; y = glConfig.vidHeight - vidmodes[i]->vdisplay; dist = ( x * x ) + ( y * y ); if ( dist < best_dist ) { best_dist = dist; best_fit = i; } } if ( best_fit != -1 ) { actualWidth = vidmodes[best_fit]->hdisplay; actualHeight = vidmodes[best_fit]->vdisplay; // change to the mode XF86VidModeSwitchToMode( dpy, scrnum, vidmodes[best_fit] ); vidmode_active = qtrue; // Move the viewport to top left XF86VidModeSetViewPort( dpy, scrnum, 0, 0 ); ri.Printf( PRINT_ALL, "XFree86-VidModeExtension Activated at %dx%d\n", actualWidth, actualHeight ); } else { fullscreen = 0; ri.Printf( PRINT_ALL, "XFree86-VidModeExtension: No acceptable modes found\n" ); } } else { ri.Printf( PRINT_ALL, "XFree86-VidModeExtension: Ignored on non-fullscreen/Voodoo\n" ); } } if ( !r_colorbits->value ) { colorbits = 24; } else { colorbits = r_colorbits->value; } if ( !Q_stricmp( r_glDriver->string, _3DFX_DRIVER_NAME ) ) { colorbits = 16; } if ( !r_depthbits->value ) { depthbits = 24; } else { depthbits = r_depthbits->value; } stencilbits = r_stencilbits->value; for ( i = 0; i < 16; i++ ) { // 0 - default // 1 - minus colorbits // 2 - minus depthbits // 3 - minus stencil if ( ( i % 4 ) == 0 && i ) { // one pass, reduce switch ( i / 4 ) { case 2: if ( colorbits == 24 ) { colorbits = 16; } break; case 1: if ( depthbits == 24 ) { depthbits = 16; } else if ( depthbits == 16 ) { depthbits = 8; } case 3: if ( stencilbits == 24 ) { stencilbits = 16; } else if ( stencilbits == 16 ) { stencilbits = 8; } } } tcolorbits = colorbits; tdepthbits = depthbits; tstencilbits = stencilbits; if ( ( i % 4 ) == 3 ) { // reduce colorbits if ( tcolorbits == 24 ) { tcolorbits = 16; } } if ( ( i % 4 ) == 2 ) { // reduce depthbits if ( tdepthbits == 24 ) { tdepthbits = 16; } else if ( tdepthbits == 16 ) { tdepthbits = 8; } } if ( ( i % 4 ) == 1 ) { // reduce stencilbits if ( tstencilbits == 24 ) { tstencilbits = 16; } else if ( tstencilbits == 16 ) { tstencilbits = 8; } else { tstencilbits = 0; } } if ( tcolorbits == 24 ) { attrib[ATTR_RED_IDX] = 8; attrib[ATTR_GREEN_IDX] = 8; attrib[ATTR_BLUE_IDX] = 8; } else { // must be 16 bit attrib[ATTR_RED_IDX] = 4; attrib[ATTR_GREEN_IDX] = 4; attrib[ATTR_BLUE_IDX] = 4; } attrib[ATTR_DEPTH_IDX] = tdepthbits; // default to 24 depth attrib[ATTR_STENCIL_IDX] = tstencilbits; visinfo = qglXChooseVisual( dpy, scrnum, attrib ); if ( !visinfo ) { continue; } ri.Printf( PRINT_ALL, "Using %d/%d/%d Color bits, %d depth, %d stencil display.\n", attrib[ATTR_RED_IDX], attrib[ATTR_GREEN_IDX], attrib[ATTR_BLUE_IDX], attrib[ATTR_DEPTH_IDX], attrib[ATTR_STENCIL_IDX] ); glConfig.colorBits = tcolorbits; glConfig.depthBits = tdepthbits; glConfig.stencilBits = tstencilbits; break; } if ( !visinfo ) { ri.Printf( PRINT_ALL, "Couldn't get a visual\n" ); return RSERR_INVALID_MODE; } /* window attributes */ attr.background_pixel = BlackPixel( dpy, scrnum ); attr.border_pixel = 0; attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone ); attr.event_mask = X_MASK; if ( vidmode_active ) { mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore | CWEventMask | CWOverrideRedirect; attr.override_redirect = True; attr.backing_store = NotUseful; attr.save_under = False; } else { mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; } win = XCreateWindow( dpy, root, 0, 0, actualWidth, actualHeight, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr ); XStoreName( dpy, win, WINDOW_CLASS_NAME ); XMapWindow( dpy, win ); if ( vidmode_active ) { XMoveWindow( dpy, win, 0, 0 ); } XFlush( dpy ); XSync( dpy,False ); // bk001130 - from cvs1.17 (mkv) ctx = qglXCreateContext( dpy, visinfo, NULL, True ); XSync( dpy,False ); // bk001130 - from cvs1.17 (mkv) qglXMakeCurrent( dpy, win, ctx ); // bk001130 - from cvs1.17 (mkv) glstring = qglGetString( GL_RENDERER ); ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glstring ); // bk010122 - new software token (Indirect) if ( !Q_stricmp( glstring, "Mesa X11" ) || !Q_stricmp( glstring, "Mesa GLX Indirect" ) ) { if ( !r_allowSoftwareGL->integer ) { ri.Printf( PRINT_ALL, "\n\n***********************************************************\n" ); ri.Printf( PRINT_ALL, " You are using software Mesa (no hardware acceleration)! \n" ); ri.Printf( PRINT_ALL, " Driver DLL used: %s\n", drivername ); ri.Printf( PRINT_ALL, " If this is intentional, add\n" ); ri.Printf( PRINT_ALL, " \"+set r_allowSoftwareGL 1\"\n" ); ri.Printf( PRINT_ALL, " to the command line when starting the game.\n" ); ri.Printf( PRINT_ALL, "***********************************************************\n" ); GLimp_Shutdown(); return RSERR_INVALID_MODE; } else { ri.Printf( PRINT_ALL, "...using software Mesa (r_allowSoftwareGL==1).\n" ); } } #endif //HAVE_GLES return RSERR_OK; }
void VID_Init(unsigned char *palette) { int i; int attrib[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 1, None }; int width = 640, height = 480; XSetWindowAttributes attr; unsigned long mask; Window root; XVisualInfo *visinfo; #ifdef USE_VMODE qbool fullscreen = true; int MajorVersion, MinorVersion; int actualWidth, actualHeight; #endif Cvar_Register (&vid_ref); Cvar_Register (&vid_mode); Cvar_Register (&vid_hwgammacontrol); Cvar_Register (&_windowed_mouse); Cvar_Register (&m_filter); vid.colormap = host_colormap; // interpret command-line params // fullscreen cmdline check #ifdef USE_VMODE if (COM_CheckParm("-window")) fullscreen = false; #endif // set vid parameters if ((i = COM_CheckParm("-width")) != 0) width = atoi(com_argv[i+1]); if ((i = COM_CheckParm("-height")) != 0) height = atoi(com_argv[i+1]); if ((i = COM_CheckParm("-conwidth")) != 0) vid.width = Q_atoi(com_argv[i+1]); else vid.width = 640; vid.width &= 0xfff8; // make it a multiple of eight if (vid.width < 320) vid.width = 320; // pick a conheight that matches with correct aspect vid.height = vid.width*3 / 4; if ((i = COM_CheckParm("-conheight")) != 0) vid.height = Q_atoi(com_argv[i+1]); if (vid.height < 200) vid.height = 200; if (!(x_disp = XOpenDisplay(NULL))) { fprintf(stderr, "Error couldn't open the X display\n"); exit(1); } scrnum = DefaultScreen(x_disp); root = RootWindow(x_disp, scrnum); #ifdef USE_VMODE // check vmode extensions supported // Get video mode list MajorVersion = MinorVersion = 0; if (!XF86VidModeQueryVersion(x_disp, &MajorVersion, &MinorVersion)) { vidmode_ext = false; } else { Com_Printf("Using XFree86-VidModeExtension Version %d.%d\n", MajorVersion, MinorVersion); vidmode_ext = true; } #endif visinfo = glXChooseVisual(x_disp, scrnum, attrib); if (!visinfo) { fprintf(stderr, "qkHack: Error couldn't get an RGB, Double-buffered, Depth visual\n"); exit(1); } // setup fullscreen size to fit display --> #ifdef USE_VMODE if (vidmode_ext) { int best_fit, best_dist, dist, x, y; XF86VidModeGetAllModeLines(x_disp, scrnum, &num_vidmodes, &vidmodes); // Are we going fullscreen? If so, let's change video mode if (fullscreen) { best_dist = 9999999; best_fit = -1; for (i = 0; i < num_vidmodes; i++) { if (width > vidmodes[i]->hdisplay || height > vidmodes[i]->vdisplay) continue; x = width - vidmodes[i]->hdisplay; y = height - vidmodes[i]->vdisplay; dist = x * x + y * y; if (dist < best_dist) { best_dist = dist; best_fit = i; } } if (best_fit != -1) { actualWidth = vidmodes[best_fit]->hdisplay; actualHeight = vidmodes[best_fit]->vdisplay; // change to the mode XF86VidModeSwitchToMode(x_disp, scrnum, vidmodes[best_fit]); vidmode_active = true; // Move the viewport to top left XF86VidModeSetViewPort(x_disp, scrnum, 0, 0); } else { fullscreen = 0; } } } #endif /* window attributes */ attr.background_pixel = 0; attr.border_pixel = 0; attr.colormap = XCreateColormap(x_disp, root, visinfo->visual, AllocNone); attr.event_mask = X_MASK; mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; // if fullscreen disable window manager decoration #ifdef USE_VMODE if (vidmode_active) { mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore | CWEventMask | CWOverrideRedirect; attr.override_redirect = True; attr.backing_store = NotUseful; attr.save_under = False; } #endif x_win = XCreateWindow(x_disp, root, 0, 0, width, height, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr); XStoreName(x_disp, x_win, PROGRAM); XMapWindow(x_disp, x_win); #ifdef USE_VMODE if (vidmode_active) { XRaiseWindow(x_disp, x_win); XWarpPointer(x_disp, None, x_win, 0, 0, 0, 0, 0, 0); XFlush(x_disp); // Move the viewport to top left XF86VidModeSetViewPort(x_disp, scrnum, 0, 0); } #endif XFlush(x_disp); ctx = glXCreateContext(x_disp, visinfo, NULL, True); glXMakeCurrent(x_disp, x_win, ctx); vid.realwidth = width; vid.realheight = height; if (vid.height > height) vid.height = height; if (vid.width > width) vid.width = width; vid.aspect = ((float)vid.height / (float)vid.width) * (320.0 / 240.0); vid.numpages = 2; InitSig(); // trap evil signals GL_Init(); Check_Gamma(palette); VID_SetPalette(palette); InitHWGamma(); Com_Printf ("Video mode %dx%d initialized.\n", width, height); SCR_InvalidateScreen (); }
/* =============== GLX_Init =============== */ int GLX_Init(glimpParms_t a) { int attrib[] = { GLX_RGBA, // 0 GLX_RED_SIZE, 8, // 1, 2 GLX_GREEN_SIZE, 8, // 3, 4 GLX_BLUE_SIZE, 8, // 5, 6 GLX_DOUBLEBUFFER, // 7 GLX_DEPTH_SIZE, 24, // 8, 9 GLX_STENCIL_SIZE, 8, // 10, 11 GLX_ALPHA_SIZE, 8, // 12, 13 None }; // these match in the array #define ATTR_RED_IDX 2 #define ATTR_GREEN_IDX 4 #define ATTR_BLUE_IDX 6 #define ATTR_DEPTH_IDX 9 #define ATTR_STENCIL_IDX 11 #define ATTR_ALPHA_IDX 13 Window root; XVisualInfo *visinfo; XSetWindowAttributes attr; XSizeHints sizehints; unsigned long mask; int colorbits, depthbits, stencilbits; int tcolorbits, tdepthbits, tstencilbits; int actualWidth, actualHeight; int i; const char *glstring; if ( !GLimp_OpenDisplay() ) { return false; } common->Printf( "Initializing OpenGL display\n" ); root = RootWindow( dpy, scrnum ); actualWidth = glConfig.vidWidth; actualHeight = glConfig.vidHeight; // Get video mode list if ( !XF86VidModeQueryVersion( dpy, &vidmode_MajorVersion, &vidmode_MinorVersion ) ) { vidmode_ext = false; common->Printf("XFree86-VidModeExtension not available\n"); } else { vidmode_ext = true; common->Printf("Using XFree86-VidModeExtension Version %d.%d\n", vidmode_MajorVersion, vidmode_MinorVersion); } GLX_TestDGA(); if ( vidmode_ext ) { int best_fit, best_dist, dist, x, y; XF86VidModeGetAllModeLines( dpy, scrnum, &num_vidmodes, &vidmodes ); // Are we going fullscreen? If so, let's change video mode if ( a.fullScreen ) { best_dist = 9999999; best_fit = -1; for (i = 0; i < num_vidmodes; i++) { if (a.width > vidmodes[i]->hdisplay || a.height > vidmodes[i]->vdisplay) continue; x = a.width - vidmodes[i]->hdisplay; y = a.height - vidmodes[i]->vdisplay; dist = (x * x) + (y * y); if (dist < best_dist) { best_dist = dist; best_fit = i; } } if (best_fit != -1) { actualWidth = vidmodes[best_fit]->hdisplay; actualHeight = vidmodes[best_fit]->vdisplay; // change to the mode XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]); vidmode_active = true; // Move the viewport to top left // FIXME: center? XF86VidModeSetViewPort(dpy, scrnum, 0, 0); common->Printf( "Free86-VidModeExtension Activated at %dx%d\n", actualWidth, actualHeight ); } else { a.fullScreen = false; common->Printf( "Free86-VidModeExtension: No acceptable modes found\n" ); } } else { common->Printf( "XFree86-VidModeExtension: not fullscreen, ignored\n" ); } } // color, depth and stencil colorbits = 24; depthbits = 24; stencilbits = 8; for (i = 0; i < 16; i++) { // 0 - default // 1 - minus colorbits // 2 - minus depthbits // 3 - minus stencil if ((i % 4) == 0 && i) { // one pass, reduce switch (i / 4) { case 2: if (colorbits == 24) colorbits = 16; break; case 1: if (depthbits == 24) depthbits = 16; else if (depthbits == 16) depthbits = 8; case 3: if (stencilbits == 24) stencilbits = 16; else if (stencilbits == 16) stencilbits = 8; } } tcolorbits = colorbits; tdepthbits = depthbits; tstencilbits = stencilbits; if ((i % 4) == 3) // reduce colorbits { if (tcolorbits == 24) tcolorbits = 16; } if ((i % 4) == 2) // reduce depthbits { if (tdepthbits == 24) tdepthbits = 16; else if (tdepthbits == 16) tdepthbits = 8; } if ((i % 4) == 1) // reduce stencilbits { if (tstencilbits == 24) tstencilbits = 16; else if (tstencilbits == 16) tstencilbits = 8; else tstencilbits = 0; } if (tcolorbits == 24) { attrib[ATTR_RED_IDX] = 8; attrib[ATTR_GREEN_IDX] = 8; attrib[ATTR_BLUE_IDX] = 8; } else { // must be 16 bit attrib[ATTR_RED_IDX] = 4; attrib[ATTR_GREEN_IDX] = 4; attrib[ATTR_BLUE_IDX] = 4; } attrib[ATTR_DEPTH_IDX] = tdepthbits; // default to 24 depth attrib[ATTR_STENCIL_IDX] = tstencilbits; visinfo = qglXChooseVisual(dpy, scrnum, attrib); if (!visinfo) { continue; } common->Printf( "Using %d/%d/%d Color bits, %d Alpha bits, %d depth, %d stencil display.\n", attrib[ATTR_RED_IDX], attrib[ATTR_GREEN_IDX], attrib[ATTR_BLUE_IDX], attrib[ATTR_ALPHA_IDX], attrib[ATTR_DEPTH_IDX], attrib[ATTR_STENCIL_IDX]); glConfig.colorBits = tcolorbits; glConfig.depthBits = tdepthbits; glConfig.stencilBits = tstencilbits; break; } if (!visinfo) { common->Printf("Couldn't get a visual\n"); return false; } // window attributes attr.background_pixel = BlackPixel(dpy, scrnum); attr.border_pixel = 0; attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone); attr.event_mask = X_MASK; if (vidmode_active) { mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore | CWEventMask | CWOverrideRedirect; attr.override_redirect = True; attr.backing_store = NotUseful; attr.save_under = False; } else { mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; } win = XCreateWindow(dpy, root, 0, 0, actualWidth, actualHeight, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr); XStoreName(dpy, win, GAME_NAME); // don't let the window be resized // FIXME: allow resize (win32 does) sizehints.flags = PMinSize | PMaxSize; sizehints.min_width = sizehints.max_width = actualWidth; sizehints.min_height = sizehints.max_height = actualHeight; XSetWMNormalHints(dpy, win, &sizehints); XMapWindow( dpy, win ); if ( vidmode_active ) { XMoveWindow( dpy, win, 0, 0 ); } XFlush(dpy); XSync(dpy, False); ctx = qglXCreateContext(dpy, visinfo, NULL, True); XSync(dpy, False); // Free the visinfo after we're done with it XFree(visinfo); qglXMakeCurrent(dpy, win, ctx); glstring = (const char *) qglGetString(GL_RENDERER); common->Printf("GL_RENDERER: %s\n", glstring); glstring = (const char *) qglGetString(GL_EXTENSIONS); common->Printf("GL_EXTENSIONS: %s\n", glstring); // FIXME: here, software GL test glConfig.isFullscreen = a.fullScreen; if ( glConfig.isFullscreen ) { Sys_GrabMouseCursor( true ); } return true; }
bool GLWindow::Create() { assert ( !IsDestroyed() ); assert ( IsDisposed() ); XVisualInfo *vi; Colormap cmap; int dpyWidth, dpyHeight; int i; int glxMajorVersion, glxMinorVersion; int vidModeMajorVersion, vidModeMinorVersion; XF86VidModeModeInfo **modes; int modeNum; int bestMode; Atom wmDelete; Window winDummy; unsigned int borderDummy; /* set best mode to current */ bestMode = 0; /* get a connection */ hDC = XOpenDisplay(0); screen = DefaultScreen(hDC); XF86VidModeQueryVersion(hDC, &vidModeMajorVersion, &vidModeMinorVersion); printf("XF86VidModeExtension-Version %d.%d\n", vidModeMajorVersion, vidModeMinorVersion); XF86VidModeGetAllModeLines(hDC, screen, &modeNum, &modes); /* save desktop-resolution before switching modes */ deskMode = *modes[0]; /* look for mode with requested resolution */ for (i = 0; i < modeNum; i++) if ((modes[i]->hdisplay == Width) && (modes[i]->vdisplay == Height)) bestMode = i; /* get an appropriate visual */ vi = glXChooseVisual(hDC, screen, attrListDbl); if (vi == NULL) { vi = glXChooseVisual(hDC, screen, attrListSgl); printf("Only Singlebuffered Visual!\n"); } else printf("Got Doublebuffered Visual!\n"); glXQueryVersion(hDC, &glxMajorVersion, &glxMinorVersion); printf("glX-Version %d.%d\n", glxMajorVersion, glxMinorVersion); /* create a GLX context */ glctx = glXCreateContext(hDC, vi, 0, GL_TRUE); /* create a color map */ cmap = XCreateColormap(hDC, RootWindow(hDC, vi->screen), vi->visual, AllocNone); attr.colormap = cmap; attr.border_pixel = 0; if (FL_fullscreen) { XF86VidModeSwitchToMode(hDC, screen, modes[bestMode]); XF86VidModeSetViewPort(hDC, screen, 0, 0); dpyWidth = modes[bestMode]->hdisplay; dpyHeight = modes[bestMode]->vdisplay; printf("Resolution %dx%d\n", dpyWidth, dpyHeight); XFree(modes); /* create a fullscreen window */ attr.override_redirect = True; attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | FocusChangeMask | EnterWindowMask | StructureNotifyMask; win = XCreateWindow(hDC, RootWindow(hDC, vi->screen), 0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &attr); XWarpPointer(hDC, None, win, 0, 0, 0, 0, 0, 0); XMapRaised(hDC, win); XGrabKeyboard(hDC, win, True, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabPointer(hDC, win, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, win, None, CurrentTime); } else { /* create a window in window mode*/ attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask | StructureNotifyMask; win = XCreateWindow(hDC, RootWindow(hDC, vi->screen), 0, 0, Width, Height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &attr); /* only set window title and handle wm_delete_events if in windowed mode */ wmDelete = XInternAtom(hDC, "WM_DELETE_WINDOW", True); XSetWMProtocols(hDC, win, &wmDelete, 1); XSetStandardProperties(hDC, win, Title, Title, None, NULL, 0, NULL); XMapRaised(hDC, win); } /* connect the glx-context to the window */ glXMakeCurrent(hDC, win, glctx); XGetGeometry(hDC, win, &winDummy, &x, &y, &Width, &Height, &borderDummy, &depth); printf("Depth %d\n", depth); if (glXIsDirect(hDC, glctx)) printf("Congrats, you have Direct Rendering!\n"); else printf("Sorry, no Direct Rendering possible!\n"); OnCreate(); this->Resize(Width, Height); return true; }