📄 i_video_xshm.c
字号:
shmdt(X_shminfo.shmaddr); shmctl(X_shminfo.shmid, IPC_RMID, 0); if( image ) { XDestroyImage(image); // is this correct? there is no shm counterpart image = NULL; } } else { if( image ) { XDestroyImage(image); image = NULL; } } if( X_mainWindow ) { XDestroyWindow(X_display, X_mainWindow); X_mainWindow=0; } } else { ; // actually do nothing here; HookXwin takes care; not very clean, but it's legacy } return;}static int createWindow(boolean isWindowedMode, int modenum){ int oktodraw; unsigned long attribmask; XSetWindowAttributes attribs; XGCValues xgcvalues; XTextProperty windowName, iconName; int valuemask; char *window_name = "Legacy"; char *icon_name = window_name; // change to the mode if(isWindowedMode && vidmode_ext) { XF86VidModeSwitchToMode(X_display, X_screen, vidmodes[0]); vidmode_active = false; } else if(isWindowedMode && !vidmode_ext) { // probably not necessary vidmode_active = false; } else { XF86VidModeSwitchToMode(X_display, X_screen, vidmodes[vidmap[modenum]]); vidmode_active = true; // Move the viewport to top left XF86VidModeSetViewPort(X_display, X_screen, 0, 0); } if(rendermode==render_soft) { // setup attributes for main window if (vidmode_active) { attribmask = CWColormap | CWSaveUnder | CWBackingStore | CWEventMask | CWOverrideRedirect; attribs.override_redirect = True; attribs.backing_store = NotUseful; attribs.save_under = False; } else attribmask = CWBorderPixel | CWColormap | CWEventMask; attribs.event_mask = KeyPressMask | KeyReleaseMask#ifndef POLL_POINTER | PointerMotionMask | ButtonPressMask | ButtonReleaseMask#endif | ExposureMask | StructureNotifyMask; attribs.colormap = X_cmap; attribs.border_pixel = 0; // create the main window X_mainWindow = XCreateWindow(X_display, RootWindow(X_display, X_screen), 0, 0, // x, y, X_width, X_height, 0, // borderwidth 8*x_depth, // depth InputOutput, X_visual, attribmask, &attribs); if(!X_mainWindow) return 0; // create the GC valuemask = GCGraphicsExposures; xgcvalues.graphics_exposures = False; X_gc = XCreateGC(X_display, X_mainWindow, valuemask, &xgcvalues ); } else { X_mainWindow = HWD.pfnHookXwin(X_display, X_width, X_height, vidmode_active); if(X_mainWindow == 0) { return 0; } } // moved here XDefineCursor(X_display, X_mainWindow, createnullcursor( X_display, X_mainWindow ) ); // set size hints for window manager, so that resizing isn't possible X_size.flags = USPosition | PSize | PMinSize | PMaxSize; X_size.min_width = X_width; X_size.min_height = X_height; X_size.max_width = X_width; X_size.max_height = X_height; // window and icon name for the window manager XStringListToTextProperty(&window_name, 1, &windowName); XStringListToTextProperty(&icon_name, 1, &iconName); // window manager hints X_wm.initial_state = NormalState; X_wm.input = True; X_wm.flags = StateHint | InputHint; // property class, in case we get a configuration file sometime X_class.res_name = "legacy"; X_class.res_class = "Legacy"; // set the properties XSetWMProperties(X_display, X_mainWindow, &windowName, &iconName, 0 /*argv*/, 0 /*argc*/, &X_size, &X_wm, &X_class); // set window manager protocol X_wm_delwin = XInternAtom(X_display, "WM_DELETE_WINDOW", False); XSetWMProtocols(X_display, X_mainWindow, &X_wm_delwin, 1); // map the window XMapWindow(X_display, X_mainWindow); if (vidmode_active) { XMoveWindow(X_display, X_mainWindow, 0, 0); XRaiseWindow(X_display, X_mainWindow); XWarpPointer(X_display, None, X_mainWindow, 0, 0, 0, 0, 0, 0); XFlush(X_display); // Move the viewport to top left XF86VidModeSetViewPort(X_display, X_screen, 0, 0); } XFlush(X_display); // wait until it is OK to draw oktodraw = 0; while (!oktodraw) { XNextEvent(X_display, &X_event); if (X_event.type == Expose && !X_event.xexpose.count) { oktodraw = 1; } } // set the focus to the window XSetInputFocus(X_display, X_mainWindow, RevertToPointerRoot, CurrentTime); // get the pointer coordinates so that the first pointer move won't // be completely wrong XQueryPointer(X_display, X_mainWindow, &dummy, &dummy, &dont_care, &dont_care, &lastmousex, &lastmousey, &dont_care); if(rendermode==render_soft) { if (doShm) { X_shmeventtype = XShmGetEventBase(X_display) + ShmCompletion; // create the image image = XShmCreateImage(X_display, X_visual, 8*x_depth, ZPixmap, 0, &X_shminfo, X_width, X_height ); grabsharedmemory(image->bytes_per_line * image->height); if (!image->data) { perror(""); I_Error("shmat() failed in InitGraphics()"); } // get the X server to attach to it if (!XShmAttach(X_display, &X_shminfo)) I_Error("XShmAttach() failed in InitGraphics()"); } else { image = XCreateImage(X_display, X_visual, 8*x_depth, ZPixmap, 0, (char*)malloc(X_width * X_height * x_depth), X_width, X_height, 8*x_depth, X_width*x_bpp ); } // if (multiply == 1 && x_depth == 1) // vid.buffer = vid.direct = screens[0] = // (unsigned char *) (image->data); // else // forced to use this in legacy 19990125 by Kin vid.buffer = vid.direct = screens[0] = (unsigned char *) malloc (vid.width * vid.height * NUMSCREENS); // added for 1.27 19990220 by Kin graphics_started = 1; } else { HWR_Startup(); graphics_started = ((X_mainWindow==0)?0:1); } return 1;}void VID_PrepareModeList(void){ int i, firstEntry; boolean finished; static boolean isVoodooChecked = false; char *rendererString, *voodooString; // I cannot detect the Voodoo earlier, so I try to catch it here if(!isVoodooChecked) { if(rendermode == render_opengl) { rendererString = HWD.pfnGetRenderer(); voodooString = strstr(rendererString, "Voodoo_Graphics"); // FIXME: if Mesa ever decides to change the this spotword, we're deep in the shit if(voodooString != NULL) { haveVoodoo = true; } } isVoodooChecked = true; } if(haveVoodoo) // nothing to do return; if(vidmode_ext && cv_fullscreen.value) { num_vidmodes = num_fullvidmodes; // initialize mapping for(i=0; i<num_vidmodes; i++) vidmap[i] = i; // bubble sort modes do { int temp; finished = true; for(i=0; i<num_vidmodes-1; i++) { if(vidmodes[vidmap[i ]]->hdisplay * vidmodes[vidmap[i ]]->vdisplay < vidmodes[vidmap[i+1]]->hdisplay * vidmodes[vidmap[i+1]]->vdisplay) { temp = vidmap[i]; vidmap[i] = vidmap[i+1]; vidmap[i+1] = temp; finished = false; } } } while(!finished); // exclude modes which are too large (to prevent X-Server problems) firstEntry = num_vidmodes; for(i=0; i<num_vidmodes; i++) { if(vidmodes[vidmap[i]]->hdisplay <= 1024 && // FIXME: get rid of "magic" numbers vidmodes[vidmap[i]]->vdisplay <= 768) { firstEntry = i; break; } } // copy modes for(i=0; i<num_vidmodes-firstEntry; i++) { vidmap[i] = vidmap[i+firstEntry]; } num_vidmodes -= firstEntry; if(num_vidmodes > 0) { // do we have any fullscreen modes at all? lowest_vidmode = num_vidmodes - 1; } else { CV_SetValue(&cv_fullscreen, 0); CONS_Printf("Only modes above 1024x768 available\nSwitching to windowed mode ...\n"); } } else { num_vidmodes = 0; } allow_fullscreen = true; return;}int VID_SetMode(int modenum) { boolean isWindowedMode; if(haveVoodoo) { if(modenum >= NUM_VOODOOMODES) return -1; destroyWindow(); isWindowedMode = true; vid.width = voodooModes[modenum][0]; vid.height = voodooModes[modenum][1]; } else if (cv_fullscreen.value && vidmode_ext) { // fullscreen if(modenum >= num_vidmodes) return -1; destroyWindow(); isWindowedMode = false; vid.width = vidmodes[vidmap[modenum]]->hdisplay; vid.height = vidmodes[vidmap[modenum]]->vdisplay; } else { // X11 if(modenum >= MAXWINMODES) return -1; destroyWindow(); isWindowedMode = true; vid.width = windowedModes[modenum][0]; vid.height = windowedModes[modenum][1]; } vid.rowbytes = vid.width; vid.recalc = 1; X_width = vid.width; // FIXME: shall we clean up X_[width,height]? X_height = vid.height; // they are identical to vid.[width,height]!!! CONS_Printf("Setting mode: %dx%d\n", vid.width, vid.height); if(!createWindow(isWindowedMode, modenum)) return 0; I_StartupMouse(); vid.modenum = modenum; return 1;}void I_StartupGraphics(void){ char *displayname; //int pnum; void *dlptr; static int firsttime = 1; // dirty if (!firsttime) return; firsttime = 0; // FIXME: catch other signals as well? signal(SIGINT, (void (*)(int)) I_Quit); signal(SIGTERM, (void (*)(int)) I_Quit); // shutdown gracefully if terminated // setup vid 19990110 by Kin vid.bpp = 1; // not optimized yet... // default size for startup vid.width = X_width = 320; vid.height = X_height = 200; CV_RegisterVar (&cv_vidwait); displayname = initDisplay(); if(M_CheckParm("-opengl")) { // only set MESA_GLX_FX if not set by set user if(!getenv("MESA_GLX_FX")) { if(M_CheckParm("-winvoodoo")) { // use windowed mode for voodoo cards if requested putenv("MESA_GLX_FX=window"); putenv("SSTV2_VGA_PASS=1"); putenv("SSTV2_NOSHUTDOWN=1"); } else { // Tell Mesa GLX to use 3Dfx driver in fullscreen mode. putenv("MESA_GLX_FX=fullscreen"); } // Disable 3Dfx Glide splash screen putenv("FX_GLIDE_NO_SPLASH=0"); } rendermode = render_opengl; //dlptr = dlopen("./r_opengl.so",RTLD_LAZY); dlptr = dlopen("./r_opengl.so",RTLD_NOW | RTLD_GLOBAL); if(!dlptr) { fprintf(stderr,"Error opening r_opengl.so!\n%s\n",dlerror()); rendermode = render_soft; } else { HWD.pfnInit = dlsym(dlptr,"Init"); HWD.pfnShutdown = dlsym(dlptr,"Shutdown"); HWD.pfnHookXwin = dlsym(dlptr,"HookXwin"); HWD.pfnSetPalette = dlsym(dlptr,"SetPalette"); HWD.pfnFinishUpdate = dlsym(dlptr,"FinishUpdate"); HWD.pfnDraw2DLine = dlsym(dlptr,"Draw2DLine"); HWD.pfnDrawPolygon = dlsym(dlptr,"DrawPolygon"); //HWD.pfnGetState = dlsym(dlptr,"GetState"); HWD.pfnSetBlend = dlsym(dlptr,"SetBlend"); HWD.pfnClearBuffer = dlsym(dlptr,"ClearBuffer"); HWD.pfnSetTexture = dlsym(dlptr,"SetTexture"); HWD.pfnReadRect = dlsym(dlptr,"ReadRect"); HWD.pfnGClipRect = dlsym(dlptr,"GClipRect"); HWD.pfnClearMipMapCache = dlsym(dlptr,"ClearMipMapCache"); HWD.pfnSetSpecialState = dlsym(dlptr,"SetSpecialState"); HWD.pfnGetRenderer = dlsym(dlptr, "GetRenderer"); //FIXME: check if all this is ok: HWD.pfnDrawMD2 = dlsym(dlptr, "DrawMD2"); HWD.pfnSetTransform = dlsym(dlptr, "SetTransform"); HWD.pfnGetTextureUsed = dlsym(dlptr, "GetTextureUsed"); HWD.pfnGetRenderVersion = dlsym(dlptr, "GetRenderVersion"); // check gl renderer lib if (HWD.pfnGetRenderVersion() != VERSION) { I_Error ("The version of the renderer doesn't match the version of the executable\nBe sure you have installed Doom Legacy properly.\n"); } } } checkVidModeExtension(); determineVidModes(); findVisual(); determineColorMask(); determineBPP(); checkForShm(displayname); createColorMap(); createWindow(true, // is windowed 0); // dummy modenum // startupscreen does not need a grabbed mouse doUngrabMouse(); graphics_started = 1; return;}void I_ShutdownGraphics(void){ // was graphics initialized anyway? if (!X_display) return; destroyWindow(); // return to normal mode if (vidmode_ext /*active*/) { XF86VidModeSwitchToMode(X_display, X_screen, vidmodes[0]); } if(rendermode != render_soft) { HWD.pfnShutdown(); } XCloseDisplay(X_display);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -