BOOL X11DRV_XF86VM_GetGammaRamp(LPDDGAMMARAMP ramp) { #ifdef X_XF86VidModeSetGamma XF86VidModeGamma gamma; Bool ret; if (xf86vm_major < 2) return FALSE; /* no gamma control */ #ifdef X_XF86VidModeSetGammaRamp else if (xf86vm_use_gammaramp) { Bool ret; wine_tsx11_lock(); ret = XF86VidModeGetGammaRamp(gdi_display, DefaultScreen(gdi_display), 256, ramp->red, ramp->green, ramp->blue); wine_tsx11_unlock(); return ret; } #endif else { wine_tsx11_lock(); ret = XF86VidModeGetGamma(gdi_display, DefaultScreen(gdi_display), &gamma); wine_tsx11_unlock(); if (ret) { GenerateRampFromGamma(ramp->red, gamma.red); GenerateRampFromGamma(ramp->green, gamma.green); GenerateRampFromGamma(ramp->blue, gamma.blue); return TRUE; } } #endif /* X_XF86VidModeSetGamma */ return FALSE; }
double xgamma_get_gamma (XF86VidModeGamma *pGamma) { g_return_val_if_fail (pGamma != NULL, 1); const Display *dpy = cairo_dock_get_Xdisplay (); g_return_val_if_fail (XF86VidModeGetGamma != NULL, 1.); if (!XF86VidModeGetGamma (dpy, DefaultScreen (dpy), pGamma)) { cd_warning ("Xgamma : unable to query gamma correction"); return 1.; } return (pGamma->red + pGamma->blue + pGamma->green) / 3; }
double xgamma_get_gamma (XF86VidModeGamma *pGamma) { g_return_val_if_fail (pGamma != NULL, 1); Display *dpy = gdk_x11_get_default_xdisplay (); g_return_val_if_fail (_xf86vidmode_supported (), 1.); if (!XF86VidModeGetGamma (dpy, DefaultScreen (dpy), pGamma)) { cd_warning ("Xgamma : unable to query gamma correction"); return 1.; } double fGamma = (pGamma->red + pGamma->blue + pGamma->green) / 3; cd_debug ("Gamma: %f, %f, %f, %f", pGamma->red, pGamma->blue, pGamma->green, fGamma); return fGamma; }
void UpdateHardwareGamma(void) { float gamma; XF86VidModeGamma x11_gamma; gamma = vid_gamma->value; x11_gamma.red = gamma; x11_gamma.green = gamma; x11_gamma.blue = gamma; XF86VidModeSetGamma(dpy, screen, &x11_gamma); /* This forces X11 to update the gamma tables */ XF86VidModeGetGamma(dpy, screen, &x11_gamma); }
static void GLW_InitGamma() { /* Minimum extension version required */ #define GAMMA_MINMAJOR 2 #define GAMMA_MINMINOR 0 glConfig.deviceSupportsGamma = qfalse; if ( vidmode_ext ) { if ( vidmode_MajorVersion < GAMMA_MINMAJOR || ( vidmode_MajorVersion == GAMMA_MINMAJOR && vidmode_MinorVersion < GAMMA_MINMINOR ) ) { ri.Printf( PRINT_ALL, "XF86 Gamma extension not supported in this version\n" ); return; } XF86VidModeGetGamma( dpy, scrnum, &vidmode_InitialGamma ); ri.Printf( PRINT_ALL, "XF86 Gamma extension initialized\n" ); glConfig.deviceSupportsGamma = qtrue; } }
/* * Shuts the SDL render backend down */ void GLimp_Shutdown(void) { /* Clear the backbuffer and make it current. This may help some broken video drivers like the AMD Catalyst to avoid artifacts in unused screen areas. */ if (SDL_WasInit(SDL_INIT_VIDEO)) { glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); GLimp_EndFrame(); } if (surface) { SDL_FreeSurface(surface); } surface = NULL; if (SDL_WasInit(SDL_INIT_EVERYTHING) == SDL_INIT_VIDEO) { SDL_Quit(); } else { SDL_QuitSubSystem(SDL_INIT_VIDEO); } #ifdef X11GAMMA if (gl_state.hwgamma == true) { XF86VidModeSetGamma(dpy, screen, &x11_oldgamma); /* This forces X11 to update the gamma tables */ XF86VidModeGetGamma(dpy, screen, &x11_oldgamma); } #endif //gl_state.hwgamma = false; }
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); }
/* * Initializes the OpenGL window */ static qboolean GLimp_InitGraphics(qboolean fullscreen) { int counter = 0; int flags; int stencil_bits; char title[24]; //QUAKETOON: forcing window fullscreen = false; if (surface && (surface->w == vid.width) && (surface->h == vid.height)) { /* Are we running fullscreen? */ int isfullscreen = (surface->flags & SDL_FULLSCREEN) ? 1 : 0; /* We should, but we don't */ if (fullscreen != isfullscreen) { SDL_WM_ToggleFullScreen(surface); } /* Do we now? */ isfullscreen = (surface->flags & SDL_FULLSCREEN) ? 1 : 0; if (fullscreen == isfullscreen) { return true; } } /* Is the surface used? */ if (surface) { SDL_FreeSurface(surface); } /* Create the window */ VID_NewWindow(vid.width, vid.height); SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); /* Initiate the flags */ flags = SDL_OPENGL; if (fullscreen) { flags |= SDL_FULLSCREEN; } /* Set the icon */ SetSDLIcon(); /* Enable vsync */ /* if (gl_swapinterval->value) { SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1); } */ while (1) { if ((surface = SDL_SetVideoMode(vid.width, vid.height, 0, flags)) == NULL) { if (counter == 1) { VID_Error(ERR_FATAL, "Failed to revert to gl_mode 4. Exiting...\n"); return false; } VID_Printf(PRINT_ALL, "SDL SetVideoMode failed: %s\n", SDL_GetError()); VID_Printf(PRINT_ALL, "Reverting to gl_mode 4 (640x480) and windowed mode.\n"); /* Try to recover */ Cvar_SetValue("gl_mode", 4); Cvar_SetValue("vid_fullscreen", 0); vid.width = 640; vid.height = 480; counter++; continue; } else { break; } } /* Initialize the stencil buffer */ if (!SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencil_bits)) { VID_Printf(PRINT_ALL, "Got %d bits of stencil.\n", stencil_bits); if (stencil_bits >= 1) { have_stencil = true; } } /* Initialize hardware gamma */ #ifdef X11GAMMA if ((dpy = XOpenDisplay(displayname)) == NULL) { VID_Printf(PRINT_ALL, "Unable to open display.\n"); } else { if (screen == -1) { screen = DefaultScreen(dpy); } gl_state.hwgamma = true; vid_gamma->modified = true; XF86VidModeGetGamma(dpy, screen, &x11_oldgamma); VID_Printf(PRINT_ALL, "Using hardware gamma via X11.\n"); } #else //gl_state.hwgamma = true; vid_gamma->modified = true; VID_Printf(PRINT_ALL, "Using hardware gamma via SDL.\n"); #endif /* Window title */ snprintf(title, sizeof(title), "QuakeToon %f", (float) VERSION); SDL_WM_SetCaption(title, title); /* No cursor */ SDL_ShowCursor(0); return true; }
/* * multithreading notes: * * This function could be accessed concurrently for different video streams, with * the pair dpy,drawable identifying each stream. */ int gl_capture_frame(gl_capture_t gl_capture, Display *dpy, GLXDrawable drawable) { struct gl_capture_video_stream_s *video; glc_message_header_t msg; glc_video_frame_header_t pic; glc_utime_t now; glc_utime_t before_capture,after_capture; char *dma; int ret = 0; if (!(gl_capture->flags & GL_CAPTURE_CAPTURING)) return 0; /* capturing not active */ gl_capture_get_video_stream(gl_capture, &video, dpy, drawable); /* get current time */ if (unlikely(gl_capture->flags & GL_CAPTURE_IGNORE_TIME)) now = video->last + gl_capture->fps; else now = glc_state_time(gl_capture->glc); /* has gl_capture->fps nanoseconds elapsed since last capture */ if ((now - video->last < gl_capture->fps) && !(gl_capture->flags & GL_CAPTURE_LOCK_FPS) && !(gl_capture->flags & GL_CAPTURE_IGNORE_TIME)) goto finish; /* not really needed until now */ gl_capture_update_video_stream(gl_capture, video); /* if PBO is not active, just start transfer and finish */ if (unlikely((gl_capture->flags & GL_CAPTURE_USE_PBO) && __sync_bool_compare_and_swap(&video->pbo_active,0,1))) { ret = gl_capture_start_pbo(gl_capture, video); video->pbo_time = now; goto finish; } if (unlikely(ps_packet_open(&video->packet, ((gl_capture->flags & GL_CAPTURE_LOCK_FPS) || (gl_capture->flags & GL_CAPTURE_IGNORE_TIME)) ? (PS_PACKET_WRITE) : (PS_PACKET_WRITE | PS_PACKET_TRY)))) goto finish; if (unlikely((ret = ps_packet_setsize(&video->packet, video->row * video->ch + sizeof(glc_message_header_t) + sizeof(glc_video_frame_header_t))))) goto cancel; msg.type = GLC_MESSAGE_VIDEO_FRAME; if (unlikely((ret = ps_packet_write(&video->packet, &msg, sizeof(glc_message_header_t))))) goto cancel; /* * if we are using PBO we will actually write previous picture to buffer. * Also, make sure that pbo_time is not in the future. This could happen if * the state time is reset by reloading the capture between a pbo start * and a pbo read. */ pic.time = (gl_capture->flags & GL_CAPTURE_USE_PBO && video->pbo_time < now)?video->pbo_time:now; pic.id = video->id; if (unlikely((ret = ps_packet_write(&video->packet, &pic, sizeof(glc_video_frame_header_t))))) goto cancel; if (video->gather_stats) before_capture = glc_state_time(gl_capture->glc); if (gl_capture->flags & GL_CAPTURE_USE_PBO) { if (unlikely((ret = gl_capture_read_pbo(gl_capture, video)))) goto cancel; ret = gl_capture_start_pbo(gl_capture, video); video->pbo_time = now; } else { if (unlikely((ret = ps_packet_dma(&video->packet, (void *) &dma, video->row * video->ch, PS_ACCEPT_FAKE_DMA)))) goto cancel; ret = gl_capture_get_pixels(gl_capture, video, dma); } if (video->gather_stats) { after_capture = glc_state_time(gl_capture->glc); video->capture_time_ns += after_capture - before_capture; } ps_packet_close(&video->packet); video->num_frames++; now = glc_state_time(gl_capture->glc); if (unlikely((gl_capture->flags & GL_CAPTURE_LOCK_FPS) && !(gl_capture->flags & GL_CAPTURE_IGNORE_TIME))) { if (now - video->last < gl_capture->fps) { struct timespec ts = { .tv_sec = (gl_capture->fps + video->last - now)/1000000000, .tv_nsec = (gl_capture->fps + video->last - now)%1000000000 }; nanosleep(&ts,NULL); } } /* increment by 1/fps seconds */ video->last += gl_capture->fps; finish: if (unlikely(ret != 0)) gl_capture_error(gl_capture, ret); if (gl_capture->flags & GL_CAPTURE_DRAW_INDICATOR) glCallList(video->indicator_list); return ret; cancel: if (ret == EBUSY) { ret = 0; glc_log(gl_capture->glc, GLC_INFO, "gl_capture", "dropped frame, buffer not ready"); } ps_packet_cancel(&video->packet); goto finish; } int gl_capture_refresh_color_correction(gl_capture_t gl_capture) { struct gl_capture_video_stream_s *video; if (unlikely(!(gl_capture->flags & GL_CAPTURE_CAPTURING))) return 0; /* capturing not active */ glc_log(gl_capture->glc, GLC_INFO, "gl_capture", "refreshing color correction"); pthread_rwlock_rdlock(&gl_capture->videolist_lock); video = gl_capture->video; while (video != NULL) { gl_capture_update_color(gl_capture, video); video = video->next; } pthread_rwlock_unlock(&gl_capture->videolist_lock); return 0; } /** \todo support GammaRamp */ int gl_capture_update_color(gl_capture_t gl_capture, struct gl_capture_video_stream_s *video) { glc_message_header_t msg_hdr; glc_color_message_t msg; XF86VidModeGamma gamma; int ret = 0; XF86VidModeGetGamma(video->dpy, video->screen, &gamma); if ((gamma.red == video->gamma_red) && (gamma.green == video->gamma_green) && (gamma.blue == video->gamma_blue)) return 0; /* nothing to update */ msg_hdr.type = GLC_MESSAGE_COLOR; msg.id = video->id; msg.red = gamma.red; msg.green = gamma.green; msg.blue = gamma.blue; /** \todo figure out brightness and contrast */ msg.brightness = msg.contrast = 0; glc_log(gl_capture->glc, GLC_INFO, "gl_capture", "color correction: brightness=%f, contrast=%f, red=%f, green=%f, blue=%f", msg.brightness, msg.contrast, msg.red, msg.green, msg.blue); if (unlikely((ret = ps_packet_open(&video->packet, PS_PACKET_WRITE)))) goto err; if (unlikely((ret = ps_packet_write(&video->packet, &msg_hdr, sizeof(glc_message_header_t))))) goto err; if (unlikely((ret = ps_packet_write(&video->packet, &msg, sizeof(glc_color_message_t))))) goto err; if (unlikely((ret = ps_packet_close(&video->packet)))) goto err; return 0; err: ps_packet_cancel(&video->packet); glc_log(gl_capture->glc, GLC_ERROR, "gl_capture", "can't write gamma correction information to buffer: %s (%d)", strerror(ret), ret); return ret; }
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; }