static void switch_to_best_mode (void) { Screen *scr = ScreenOfDisplay (display, screen); int w = WidthOfScreen (scr); int h = HeightOfScreen (scr); int d = DefaultDepthOfScreen (scr); #ifdef USE_VIDMODE_EXTENSION int i, best; if (vidmodeavail) { best = 0; for (i = 1; i < vidmodecount; i++) { if (allmodes[i]->hdisplay >= current_width && allmodes[i]->vdisplay >= current_height && allmodes[i]->hdisplay <= allmodes[best]->hdisplay && allmodes[i]->vdisplay <= allmodes[best]->vdisplay) best = i; } write_log ("entering DGA mode: %dx%d (%d, %d)\n", allmodes[best]->hdisplay, allmodes[best]->vdisplay, current_width, current_height); XF86VidModeSwitchToMode (display, screen, allmodes[best]); XF86VidModeSetViewPort (display, screen, 0, 0); } #endif XMoveWindow (display, mywin, 0, 0); XWarpPointer (display, None, rootwin, 0, 0, 0, 0, 0, 0); XF86DGADirectVideo (display, screen, XF86DGADirectGraphics | XF86DGADirectMouse | XF86DGADirectKeyb); XF86DGASetViewPort (display, screen, 0, 0); memset (fb_addr, 0, (w * h) * (d / 8)); }
// // KILLGLWINDOW // static GLvoid KillGLWindow(GLvoid) // Properly Kill The Window { if (GLWin.ctx) { if (!glXMakeCurrent(GLWin.dpy, None, NULL)) { printf("released failed\n"); } // end of teh if glXDestroyContext(GLWin.dpy, GLWin.ctx); GLWin.ctx = NULL; } // end of the if // switch back to original resolution if (GLWin.fs) { XF86VidModeSwitchToMode(GLWin.dpy, GLWin.screen, &GLWin.deskMode); XF86VidModeSetViewPort(GLWin.dpy, GLWin.screen, 0, 0); } // end of the if XCloseDisplay(GLWin.dpy); ShutdownGL(); } // end of the function
void S9xGraphicsMode () { if (is_graphics) return; XSelectInput (ourdisp, inputwin, KeyPressMask | KeyReleaseMask); XSetInputFocus (ourdisp, inputwin, RevertToNone, CurrentTime); XGrabKeyboard (ourdisp, inputwin, True, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabPointer (ourdisp, inputwin, True, 0, GrabModeAsync, GrabModeAsync, inputwin, None, CurrentTime); XFlush(ourdisp); XAutoRepeatOff (ourdisp); #ifdef USE_XF86VIDMODE if (orig_mode != mod320x240) { XF86VidModeSwitchToMode (ourdisp,ourscreen, mod320x240); } XFlush (ourdisp); XF86VidModeSetViewPort (ourdisp, ourscreen, 0, 0); XFlush (ourdisp); #endif XF86DGADirectVideo (ourdisp, ourscreen, XF86DGADirectGraphics); memset ((void *) ourvideo.vidMemBegin, 0, ourvideo.width * 240 * ourvideo.screendepth); is_graphics = TRUE; XFlush (ourdisp); }
Game::~Game() { #ifdef DEBUG fprintf(stdout, "Game destructor\n"); #endif #if defined(SDL_VIDEO) SDL_FreeSurface(_screen); #endif #if defined(HW_RENDER) #if defined(X11_RENDER) if(_GLWin.ctx) { if(!glXMakeCurrent(_GLWin.dpy, None, NULL)) { fprintf(stderr, "Error releasing drawing context\n"); } glXDestroyContext(_GLWin.dpy, _GLWin.ctx); _GLWin.ctx = NULL; } if(_GLWin.fs) { XF86VidModeSwitchToMode(_GLWin.dpy, _GLWin.screen, &_GLWin.deskMode); XF86VidModeSetViewPort(_GLWin.dpy, _GLWin.screen, 0, 0); } XCloseDisplay(_GLWin.dpy); #endif #endif }
void Window::Close(void) { if (this->ctx) { if (!glXMakeCurrent(this->dpy, None, NULL)) std::cout << "Could not release drawing context." << std::endl; glXDestroyContext(this->dpy, this->ctx); this->ctx = NULL; } if (this->fs) { XF86VidModeSwitchToMode(this->dpy, this->screen, &this->deskMode); XF86VidModeSetViewPort(this->dpy, this->screen, 0, 0); } else XUngrabPointer(this->dpy, CurrentTime); XKeyboardControl _kb; _kb.auto_repeat_mode = this->deskKeyboardState.global_auto_repeat; XChangeKeyboardControl(this->dpy, KBAutoRepeatMode, &_kb); XCloseDisplay(this->dpy); };
static void xfvm_post_setup(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d) { int x = 0, y = 0; XWindowAttributes xwa; #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA /* TwinView workarounds, nothing to do here, since we can't really change or restore modes */ if (s->xinerama_available && s->xinerama_screen_count != s->xfvm_screen_count) { return; } #endif int adapter = _al_xglx_get_adapter(s, d, false); XGetWindowAttributes(s->x11display, d->window, &xwa); xfvm_get_display_offset(s, adapter, &x, &y); /* some window managers like to move our window even if we explicitly tell it not to * so we need to get the correct offset here */ x = xwa.x - x; y = xwa.y - y; ALLEGRO_DEBUG("xfvm set view port: %ix%i\n", x, y); XF86VidModeSetViewPort(s->x11display, adapter, x, y); }
void CL_DisplayWindow_OpenGL::set_windowed() { if(!fullscreen) return; if (0) { // FIXME: See FIXME in set_fullscreen // Hide window XUnmapWindow(disp, window); XSync(disp, True); // Turn on WM control attributes.override_redirect = False; XChangeWindowAttributes(disp, window, CWBorderPixel | CWColormap | CWOverrideRedirect, &attributes); XMoveResizeWindow(disp, window, 0, 0, fullscreen_width, fullscreen_height); XMapRaised(disp, window); XSync(disp, True); } fullscreen = false; // Only restore mode if we ever switched mode. if (old_x != -1 || old_y != -1) { XF86VidModeSwitchToMode(disp, 0, &old_mode); XF86VidModeSetViewPort(disp, 0, old_x, old_y); } XUngrabPointer(disp, CurrentTime); XSync(disp, True); }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetViewPort(JNIEnv *env, jclass unused, jlong display_ptr, jlong window_ptr, jint screen) { Display *disp = (Display *)(intptr_t)display_ptr; Window win = (Window)window_ptr; XWindowAttributes win_attribs; XGetWindowAttributes(disp, win, &win_attribs); XF86VidModeSetViewPort(disp, screen, win_attribs.x, win_attribs.y); }
/******************************************************************** * O P E R A T I O N S * ********************************************************************/ bool VOGLWindow::Create(VWindowOpts *pOpts) { #if VIPER_PLATFORM == PLATFORM_WINDOWS #elif VIPER_PLATFORM == PLATFORM_MAC #elif VIPER_PLATFORM == PLATFORM_LINUX Atom vWMDelete; Window vWinDmmy; VUINT vBorderDummy; mOpts.mFullScreen = pOpts->mFullScreen; mOpts.mWidth = pOpts->mWidth; mOpts.mHeight = pOpts->mHeight; mAttr.colormap = XCreateColormap(mDpy, RootWindow(mDpy, mVInfo->screen), mVInfo->visual, AllocNone); mAttr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask; if (mOpts.mFullScreen) { XF86VidModeSwitchToMode(mDpy, mScreen, mMode); XF86VidModeSetViewPort(mDpy, mScreen, 0, 0); mAttr.override_redirect = True; mWin = XCreateWindow(mDpy, RootWindow(mDpy, mVInfo->screen), 0, 0, mOpts.mWidth, mOpts.mHeight, 0, mVInfo->depth, InputOutput, mVInfo->visual, CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &mAttr ); } else { mWin = XCreateWindow(mDpy, RootWindow(mDpy, mVInfo->screen), 0, 0, mOpts.mWidth, mOpts.mHeight, 0, mVInfo->depth, InputOutput, mVInfo->visual, CWBorderPixel | CWColormap | CWEventMask, &mAttr ); vWMDelete = XInternAtom(mDpy, "WM_DELETE_WINDOW", True); XSetWMProtocols(mDpy, mWin, &vWMDelete, 1); XSetStandardProperties(mDpy, mWin, "", "", None, NULL, 0, NULL); } XMapRaised(mDpy, mWin); mCtx = glXCreateContext(mDpy, mVInfo, 0, GL_TRUE); if (mCtx == NULL) { VTRACE(_CL("Unable to create context\n")); return false; } if (!glXMakeCurrent(mDpy, mWin, mCtx)) return false; if (glXIsDirect(mDpy, mCtx)) VTRACE(_CL("Direct Rendering: true\n")); else VTRACE(_CL("Direct Rendering: false\n")); #endif return true; }
///////////////////////////////////////////////////////// // destroy window // ///////////////////////////////////////////////////////// void gemglxwindow :: destroy(void) { /* both glXMakeCurrent() and XCloseDisplay() will crash the application * if the handler of the display (m_pimpl->dpy) is invalid, e.g. because * somebody closed the Gem-window with xkill or by clicking on the "x" of the window */ if (m_pimpl->dpy) { int err=0; #ifdef HAVE_LIBXXF86VM if (m_pimpl->fs) { XF86VidModeSwitchToMode(m_pimpl->dpy, m_pimpl->screen, &m_pimpl->deskMode); XF86VidModeSetViewPort(m_pimpl->dpy, m_pimpl->screen, 0, 0); m_pimpl->fs=0; } #endif /* patch by cesare marilungo to prevent the crash "on my laptop" */ glXMakeCurrent(m_pimpl->dpy, None, NULL); /* this crashes if no window is there! */ if (m_pimpl->glxcontext) { // this crashes sometimes on my laptop: glXDestroyContext(m_pimpl->dpy, m_pimpl->glxcontext); } if (m_pimpl->win) { XUnmapWindow (m_pimpl->dpy, m_pimpl->win); err=XDestroyWindow(m_pimpl->dpy, m_pimpl->win); if(err) { verbose(1, "XDestroyWindow returned %d", err); } } if (m_pimpl->cmap) { err=XFreeColormap(m_pimpl->dpy, m_pimpl->cmap); if(err) { verbose(1, "XFreeColormap returned %d", err); } } XFlush( m_pimpl->dpy ); err=XCloseDisplay(m_pimpl->dpy); /* this crashes if no window is there */ if(err) { verbose(1, "XCloseDisplay returned %d", err); } } m_pimpl->dpy = NULL; m_pimpl->win = 0; m_pimpl->cmap = 0; m_pimpl->glxcontext = NULL; if(m_pimpl->delete_atom) { m_pimpl->delete_atom=None; /* not very sophisticated destruction...*/ } destroyGemWindow(); }
void ContextGL_X11::Restore_Desktop(){ print_line("Debug: Restore Original Desktop Resolution"); XF86VidModeSwitchToMode( x11_display, screenBackup, &desktopMode ); XF86VidModeSetViewPort( x11_display, screenBackup, 0, 0 ); return; }
bool x11_enter_fullscreen(Display *dpy, unsigned width, unsigned height, XF86VidModeModeInfo *desktop_mode) { XF86VidModeModeInfo mode; if (!get_video_mode(dpy, width, height, &mode, desktop_mode)) return false; if (!XF86VidModeSwitchToMode(dpy, DefaultScreen(dpy), &mode)) return false; XF86VidModeSetViewPort(dpy, DefaultScreen(dpy), 0, 0); return true; }
void fxwt::destroy_graphics() { info("Shutting down GLX"); glXDestroyContext(fxwt_x_dpy, glx_ctx); XDestroyWindow(fxwt_x_dpy, fxwt_x_win); #ifdef USE_XF86VIDMODE if(fullscreen) { XF86VidModeSwitchToMode(fxwt_x_dpy, DefaultScreen(fxwt_x_dpy), &orig_mode); XF86VidModeSetViewPort(fxwt_x_dpy, DefaultScreen(fxwt_x_dpy), 0, 0); } #endif // USE_XF86VIDMODE XCloseDisplay(fxwt_x_dpy); }
/* If the viewport has been scrolled since the screen was blanked, then scroll it back to where it belongs. This function only exists to patch over a very brief race condition. */ static void undo_vp_motion (saver_info *si) { #ifdef HAVE_XF86VMODE saver_preferences *p = &si->prefs; int screen; int real_nscreens = ScreenCount (si->dpy); int event, error; if (!XF86VidModeQueryExtension (si->dpy, &event, &error)) return; for (screen = 0; screen < real_nscreens; screen++) { saver_screen_info *ssi = &si->screens[screen]; int x, y; Bool status; if (ssi->blank_vp_x == -1 && ssi->blank_vp_y == -1) break; if (!XF86VidModeGetViewPort (si->dpy, screen, &x, &y)) return; if (ssi->blank_vp_x == x && ssi->blank_vp_y == y) return; /* We're going to move the viewport. The mouse has just been grabbed on (and constrained to, thus warped to) the password window, so it is no longer near the edge of the screen. However, wait a bit anyway, just to make sure the server drains its last motion event, so that the screen doesn't continue to scroll after we've reset the viewport. */ XSync (si->dpy, False); usleep (250000); /* 1/4 second */ XSync (si->dpy, False); status = XF86VidModeSetViewPort (si->dpy, screen, ssi->blank_vp_x, ssi->blank_vp_y); if (!status) fprintf (stderr, "%s: %d: unable to move vp from (%d,%d) back to (%d,%d)!\n", blurb(), screen, x, y, ssi->blank_vp_x, ssi->blank_vp_y); else if (p->verbose_p) fprintf (stderr, "%s: %d: vp moved to (%d,%d); moved it back to (%d,%d).\n", blurb(), screen, x, y, ssi->blank_vp_x, ssi->blank_vp_y); } #endif /* HAVE_XF86VMODE */ }
void DestroyWindowGL(GL_Window* window) { if(window->init.ctx ) { if( !glXMakeCurrent(window->init.dpy, None, NULL ) ) { fprintf( stderr, "Error releasing drawing context\n" ); } glXDestroyContext( window->init.dpy, window->init.ctx ); } if(window->init.isFullScreen) { XF86VidModeSwitchToMode( window->init.dpy, window->init.screen, &window->init.deskMode ); XF86VidModeSetViewPort( window->init.dpy, window->init.screen, 0, 0 ); } XCloseDisplay( window->init.dpy ); }
void fv_switch_to_mode(int i) { if ((!vmode_modes) || (i<0)) { ERROR_MSG("fv_switch_to_mode: no valid mode available.\n"); return; } vmode_mode_selected = i; win_width = vmode_modes[i]->hdisplay; win_height = vmode_modes[i]->vdisplay; TRACE_MSG("fv_switch_to_mode: mode selected: %d (%d,%d).\n", vmode_mode_selected, win_width, win_height); XF86VidModeSwitchToMode(Xdpy, Xscreen, vmode_modes[i]); XF86VidModeSetViewPort(Xdpy, Xscreen, 0, 0); }
void OpenGLApp::exitAPI(){ delete renderer; glXMakeCurrent(display, None, NULL); glXDestroyContext(display, glContext); if (fullscreen){ if (XF86VidModeSwitchToMode(display, screen, dmodes[0])){ XF86VidModeSetViewPort(display, screen, 0, 0); } } XFree(dmodes); XFreeCursor(display, blankCursor); XDestroyWindow(display, window); XSync(display, False); }
bool LinuxDisplayMode::doSet(int index, bool position) { // ignore attempts to set video format to current format. // normally this only happens when restoring the default // format, when BzfDisplay deliberately forces the change. // that's useful for win32 where the OS knows the right // format and will ignore calls to switch the current // format. however, irix isn't so clever and may cause // the display to flicker even when the format isn't // really changing. if (index == lastResolution || numResolutions <= 1) return true; // deactivate windows before resolution change. if we don't do this // then the app will almost certainly crash in the OpenGL driver. XWindow::deactivateAll(); // change resolution if (XF86VidModeSwitchToMode(display->getRep()->getDisplay(), display->getRep()->getScreen(), resolutions[index])) { if (position) { // kludge for accelerated GLX. when we set the view port after // changing the resolution just before quiting, GLX does not // release the display to X server control. or something like // that. the effect is that you see the game window still on // the screen but maybe shifted around and you can't see any of // the other windows. without this code, a workaround for the // problem is ctrl_alt_+ or ctrl_alt_- to force a resize. XF86VidModeSetViewPort(display->getRep()->getDisplay(), display->getRep()->getScreen(), 0, 0); } XSync(display->getRep()->getDisplay(), false); lastResolution = index; // reactivate previously deactivated window after change XWindow::reactivateAll(); return true; } // reactivate previously deactivated window after change XWindow::reactivateAll(); return false; }
/* function to release/destroy our resources and restoring the old desktop */ GLvoid killGLWindow(GLvoid) { if (GLWin.ctx) { if (!glXMakeCurrent(GLWin.dpy, None, NULL)) { printf("Could not release drawing context.\n"); } glXDestroyContext(GLWin.dpy, GLWin.ctx); GLWin.ctx = NULL; } /* switch back to original desktop resolution if we were in fs */ if (GLWin.fs) { XF86VidModeSwitchToMode(GLWin.dpy, GLWin.screen, &GLWin.deskMode); XF86VidModeSetViewPort(GLWin.dpy, GLWin.screen, 0, 0); } XCloseDisplay(GLWin.dpy); }
static void vidmode_center_canvas(struct video_canvas_s *canvas) { Display *vm_display; if (vm_available == 0) { return; } if (active_canvas != canvas) { return; } vm_display = x11ui_get_display_ptr(); x11ui_move_canvas_window(canvas->emuwindow, 0, 0); ui_dispatch_events(); x11ui_canvas_position(canvas->emuwindow, &x, &y); XF86VidModeSetViewPort(vm_display, screen, x + xoffs, y + yoffs); ui_dispatch_events(); }
void GLWindow::Dispose() { if (glctx) { if (!glXMakeCurrent(hDC, None, NULL)) printf("Could not release drawing context.\n"); glXDestroyContext(hDC, glctx); } /* switch back to original desktop resolution if we were in fs */ if (FL_fullscreen) { XF86VidModeSwitchToMode(hDC, screen, &deskMode); XF86VidModeSetViewPort(hDC, screen, 0, 0); } if (hDC) XCloseDisplay(hDC); glctx = NULL; hDC = NULL; }
void GLWindow::free() { #ifdef _WIN32 if(mhRC) { if(!wglMakeCurrent(NULL, NULL)) { } if (!wglDeleteContext(mhRC)) { } mhRC = 0; } if(mhDC && !ReleaseDC(mhWnd, mhDC)) { mhDC = 0; } if(mhWnd && !DestroyWindow(mhWnd)) { mhWnd = 0; } if(!UnregisterClass("OpenGL", mhInstance)) { mhInstance = 0; } #else if(mCtx) { if(!glXMakeCurrent(mDisplay, None, NULL)) { printf("Could not release drawing context.\n"); } /* destroy the context */ glXDestroyContext(mDisplay, mCtx); mCtx = NULL; } /* switch back to original desktop resolution if we were in fullscreen */ if( mFullscreen ) { XF86VidModeSwitchToMode(mDisplay, mScreen, &mDeskMode); XF86VidModeSetViewPort(mDisplay, mScreen, 0, 0); } XCloseDisplay(mDisplay); #endif }
void Sys_KillWindow(void) { if (g_Window.glctx) { if (!glXMakeCurrent(g_Window.display, None, NULL)) { fprintf(stderr, "Can't release drawing context\n"); } glXDestroyContext(g_Window.display, g_Window.glctx); g_Window.glctx = NULL; } if (g_Window.fs) { XF86VidModeSwitchToMode(g_Window.display, g_Window.screen, &g_Window.desktop_mode); XF86VidModeSetViewPort(g_Window.display, g_Window.screen, 0, 0); } if (g_Player != NULL) { free(g_Player); } XCloseDisplay(g_Window.display); }
MWindow::~MWindow(void) { if(display) { if(context) { glXMakeCurrent(display, None, NULL); glXDestroyContext(display, context); context = NULL; } if(m_fullscreen) { #ifndef __CYGWIN__ XF86VidModeSwitchToMode(display, screen, &desktopMode); XF86VidModeSetViewPort(display, screen, 0, 0); #endif } XCloseDisplay(display); } }
void fv_resetGeometry() { #ifdef HAVE_XF86_VMODE int oldMode, i; if (fullscreen) { XF86VidModeGetAllModeLines(Xdpy, Xscreen, &vmode_nb_modes, &vmode_modes); oldMode = 0; for (i=0; i < vmode_nb_modes; i++) { if ((vmode_modes[i]->hdisplay == oldx) && (vmode_modes[i]->vdisplay==oldy)) { oldMode = i; break; } } XF86VidModeSwitchToMode(Xdpy, Xscreen, vmode_modes[oldMode]); XF86VidModeSetViewPort(Xdpy, Xscreen, 0, 0); XFlush(Xdpy); } #endif /* HAVE_XF86_VMODE */ }
void X11Device::shutdown() { X11Session *session = static_cast<X11Session *>(getSession()); Log(EDebug, "Shutting down X11 device"); Device::shutdown(); setVisible(false); XDestroyWindow(session->m_display, m_window); XFree(m_visinfo); if (m_fullscreen) { /* Switch back to the previous screen resolution */ XF86VidModeSwitchToMode(session->m_display, session->m_screen, &m_previousMode); XF86VidModeSetViewPort(session->m_display, session->m_screen, 0, 0); } /* In case auto_repeat was left on */ XKeyboardState xkbs; XAutoRepeatOn(session->m_display); XGetKeyboardControl(session->m_display, &xkbs); if (!xkbs.global_auto_repeat) Log(EWarn, "Unable to restore the keyboard auto-repeat flag"); m_initialized = false; }
static LONG X11DRV_XF86VM_SetCurrentMode(int mode) { DWORD dwBpp = screen_bpp; /* only set modes from the original color depth */ if (dwBpp != dd_modes[mode].dwBPP) { FIXME("Cannot change screen BPP from %d to %d\n", dwBpp, dd_modes[mode].dwBPP); } mode = mode % real_xf86vm_mode_count; wine_tsx11_lock(); TRACE("Resizing X display to %dx%d\n", real_xf86vm_modes[mode]->hdisplay, real_xf86vm_modes[mode]->vdisplay); XF86VidModeSwitchToMode(gdi_display, DefaultScreen(gdi_display), real_xf86vm_modes[mode]); #if 0 /* it is said that SetViewPort causes problems with some X servers */ XF86VidModeSetViewPort(gdi_display, DefaultScreen(gdi_display), 0, 0); #else XWarpPointer(gdi_display, None, DefaultRootWindow(gdi_display), 0, 0, 0, 0, 0, 0); #endif XSync(gdi_display, False); wine_tsx11_unlock(); X11DRV_resize_desktop( real_xf86vm_modes[mode]->hdisplay, real_xf86vm_modes[mode]->vdisplay ); return DISP_CHANGE_SUCCESSFUL; }
/* =========== IN_ProcessEvents =========== */ void IN_ProcessEvents (void) { // handle the mouse state when windowed if that's changed if (!vidmode_fullscreen) { if ( key_dest == key_game && !mouse_grab_active && vid_activewindow ) // if ( key_dest != key_console && !mouse_grab_active && vid_activewindow ) { IN_GrabMouse (); } else if ( key_dest != key_game && mouse_grab_active ) // else if ( key_dest == key_console && mouse_grab_active ) { IN_UngrabMouse (); } } // getting and handle events { XEvent x_event; static qboolean active = true; if (!x_disp) return; while (XPending(x_disp)) { XNextEvent(x_disp, &x_event); switch (x_event.type) { case KeyPress: // key pressed case KeyRelease: // key released Key_Event(XLateKey(&x_event.xkey), x_event.type == KeyPress); break; case MotionNotify: // mouse moved if (mouse_grab_active) { if (dga_mouse_active) { mouse_x += (float)x_event.xmotion.x_root; mouse_y += (float)x_event.xmotion.y_root; } else { mouse_x = (float)x_event.xmotion.x - (float)(vid.width / 2); mouse_y = (float)x_event.xmotion.y - (float)(vid.height / 2); if (mouse_x || mouse_y) // do warp { // move the mouse to the window center again XWarpPointer(x_disp, None, x_win, 0, 0, 0, 0, vid.width / 2, vid.height / 2); } } } break; case ButtonPress: // mouse button pressed case ButtonRelease: // mouse button released switch (x_event.xbutton.button) { case 1: Key_Event (K_MOUSE1, x_event.type == ButtonPress); break; case 2: Key_Event (K_MOUSE3, x_event.type == ButtonPress); break; case 3: Key_Event (K_MOUSE2, x_event.type == ButtonPress); break; case 4: Key_Event (K_MWHEELUP, x_event.type == ButtonPress); break; case 5: Key_Event (K_MWHEELDOWN, x_event.type == ButtonPress); break; case 6: Key_Event (K_MOUSE4, x_event.type == ButtonPress); break; case 7: Key_Event (K_MOUSE5, x_event.type == ButtonPress); break; case 8: Key_Event (K_MOUSE6, x_event.type == ButtonPress); break; case 9: Key_Event (K_MOUSE7, x_event.type == ButtonPress); break; case 10: Key_Event (K_MOUSE8, x_event.type == ButtonPress); break; } break; case CreateNotify: // window created window_x = x_event.xcreatewindow.x; window_y = x_event.xcreatewindow.y; window_width = x_event.xcreatewindow.width; window_height = x_event.xcreatewindow.height; break; case ConfigureNotify: // window changed size/location window_x = x_event.xconfigure.x; window_y = x_event.xconfigure.y; window_width = x_event.xconfigure.width; window_height = x_event.xconfigure.height; // check for resize if (!vidmode_fullscreen) { if (window_width < 320) window_width = 320; if (window_height < 200) window_height = 200; vid.width = window_width; vid.height = window_height; vid.conwidth = vid.width; vid.conheight = vid.height; vid.recalc_refdef = true; // force a surface cache flush } break; case DestroyNotify: // window has been destroyed Sys_Quit (0); break; case ClientMessage: // window manager messages if ((x_event.xclient.format == 32) && ((unsigned int)x_event.xclient.data.l[0] == wm_delete_window_atom)) Sys_Quit (0); break; case MapNotify: // window restored case UnmapNotify: // window iconified/rolledup/whatever vid_hiddenwindow = (x_event.type == UnmapNotify); case FocusIn: // window is now the input focus case FocusOut: // window is no longer the input focus switch (x_event.xfocus.mode) { case NotifyNormal: case NotifyGrab: case NotifyUngrab: vid_activewindow = (x_event.type == FocusIn); break; } if(vidmode_fullscreen) { if(x_event.type == MapNotify) { // set our video mode XF86VidModeSwitchToMode(x_disp, scrnum, &game_vidmode); // move the viewport to top left XF86VidModeSetViewPort(x_disp, scrnum, 0, 0); } else if(x_event.type == UnmapNotify) { // set our video mode XF86VidModeSwitchToMode(x_disp, scrnum, &init_vidmode); } } else //if (!vidmode_fullscreen) { // enable/disable sound, set/restore gamma and grab/ungrab keyb // on focus gain/loss if (vid_activewindow && !vid_hiddenwindow && !active) { S_UnblockSound (); S_ClearBuffer (); VID_Gamma_Set (); IN_GrabKeyboard(); active = true; } else if (active) { S_BlockSound (); S_ClearBuffer (); VID_Gamma_Restore (); IN_UngrabKeyboard(); active = false; } } // fix the leftover Alt from any Alt-Tab or the like that switched us away Key_ClearStates (); break; case EnterNotify: // mouse entered window case LeaveNotify: // mouse left window vid_notifywindow = (x_event.type == EnterNotify); break; } } } }
/* =============== 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; }
/* ** 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; }