📄 i_video_xshm.c
字号:
// event.data1 = ((mask & Button1Mask) ? 1 : 0) | // ((mask & Button2Mask) ? 2 : 0) | // ((mask & Button3Mask) ? 4 : 0); event.data2 = (newmousex - lastmousex) << 2; event.data3 = -((newmousey - lastmousey) << 2); D_PostEvent(&event); if ((newmousex < 1) || (newmousey < 1) || (newmousex > X_width-2) || (newmousey > X_height-2)) { XWarpPointer(X_display, None, X_mainWindow, 0, 0, 0, 0, X_width/2, X_height/2); lastmousex = X_width/2; lastmousey = X_height/2; } else { lastmousex = newmousex; lastmousey = newmousey; }#endif } while (XPending(X_display)) I_GetEvent();}//// I_UpdateNoBlit//void I_UpdateNoBlit(void){ /* empty */}//// I_FinishUpdate//void I_FinishUpdate(void){ static int lasttic; int tics; int i; if(rendermode==render_soft) { // draws little dots on the bottom of the screen if (devparm) { i = I_GetTime(); tics = i - lasttic; lasttic = i; if (tics > 20) tics = 20; for (i=0 ; i<tics*2 ; i+=2) screens[0][ (vid.height-2)*vid.width + i + 3] = 0xff; for ( ; i<20*2 ; i+=2) screens[0][ (vid.height-2)*vid.width + i + 3] = 0x0; } // colormap transformation dependend on X server color depth if (x_bpp == 2) { int x,y; int xstart = vid.width-1; unsigned char* ilineptr; unsigned short* olineptr; y = vid.height; while (y--) { olineptr = (unsigned short *) &(image->data[y*X_width*x_bpp]); ilineptr = (unsigned char*) (screens[0]+y*X_width); x = xstart; do { olineptr[x] = x_colormap2[ilineptr[x]]; } while (x--); } } else if (x_bpp == 3) { int x,y; int xstart = vid.width-1; unsigned char* ilineptr; unsigned char* olineptr; y = vid.height; while (y--) { olineptr = (unsigned char *) &image->data[y*X_width*x_bpp]; ilineptr = (unsigned char*) (screens[0]+y*X_width); x = xstart; do { memcpy(olineptr+3*x,x_colormap3+3*ilineptr[x],3); } while (x--); } } else if (x_bpp == 4) { int x,y; int xstart = vid.width-1; unsigned char* ilineptr; unsigned int* olineptr; y = vid.height; while (y--) { olineptr = (unsigned int *) &(image->data[y*X_width*x_bpp]); ilineptr = (unsigned char*) (screens[0]+y*X_width); x = xstart; do { olineptr[x] = x_colormap4[ilineptr[x]]; } while (x--); } } else { // bpp = 1, multiply = 1 19990125 by Kin // VID_BlitLinearScreen does not work???? //VID_BlitLinearScreen ( screens[0], image->data,vid.width, // vid.height, vid.width, vid.width ); memcpy(image->data,screens[0],vid.width*vid.height); } if (doShm) { if (!XShmPutImage(X_display, X_mainWindow, X_gc, image, 0, 0, 0, 0, X_width, X_height, True )) I_Error("XShmPutImage() failed\n"); // wait for it to finish and processes all input events shmFinished = false; do { if (XPending(X_display)) I_GetEvent(); else I_WaitVBL(1); } while (!shmFinished); } else { // draw the image XPutImage( X_display, X_mainWindow, X_gc, image, 0, 0, 0, 0, X_width, X_height ); } } else { HWD.pfnFinishUpdate(cv_vidwait.value); }}//// I_ReadScreen//void I_ReadScreen(byte* scr){ memcpy (scr, screens[0], vid.width*vid.height);}//// Palette stuff.//static XColor colors[256];static void UploadNewPalette(Colormap cmap, RGBA_t *palette){ register int i; register int c; static boolean firstcall = true;#ifdef __cplusplus if (X_visualinfo.c_class == PseudoColor && X_visualinfo.depth == 8)#else if (X_visualinfo.class == PseudoColor && X_visualinfo.depth == 8)#endif { // initialize the colormap if (firstcall) { firstcall = false; for (i=0 ; i<256 ; i++) { colors[i].pixel = i; colors[i].flags = DoRed|DoGreen|DoBlue; } } // set the X colormap entries for (i=0 ; i<256 ; i++,palette++) { c = palette->s.red; colors[i].red = (c<<8) + c; c = palette->s.green; colors[i].green = (c<<8) + c; c = palette->s.blue; colors[i].blue = (c<<8) + c; } // store the colors to the current colormap XStoreColors(X_display, cmap, colors, 256); }}static void EmulateNewPalette(RGBA_t *palette){ register int i; for (i=0 ; i<256 ; i++,palette++) { switch(x_bpp) { case 2: x_colormap2[i] = ((palette->s.red>>x_red_mask)<<x_red_offset) | ((palette->s.green>>x_green_mask)<<x_green_offset) | ((palette->s.blue>>x_blue_mask)<<x_blue_offset); break; case 3: x_colormap3[3*i+x_red_offset] = palette->s.red; x_colormap3[3*i+x_green_offset] = palette->s.green; x_colormap3[3*i+x_blue_offset] = palette->s.blue; break; case 4: x_colormap4[i] = 0; ((unsigned char*)(x_colormap4+i))[x_red_offset] = palette->s.red; ((unsigned char*)(x_colormap4+i))[x_green_offset] = palette->s.green; ((unsigned char*)(x_colormap4+i))[x_blue_offset] = palette->s.blue; break; } }}//// I_SetPalette//void I_SetPalette(RGBA_t* palette){ if( rendermode == render_soft ) { if (x_pseudo) UploadNewPalette(X_cmap, palette); else EmulateNewPalette(palette); }}//// This function is probably redundant,// if XShmDetach works properly.// ddt never detached the XShm memory,// thus there might have been stale// handles accumulating.//static void grabsharedmemory(int size){ int key = ('d'<<24) | ('o'<<16) | ('o'<<8) | 'm'; struct shmid_ds shminfo; int minsize = 320*200; int id; int rc; int pollution=5; // try to use what was here before do { id = shmget((key_t) key, minsize, 0777); // just get the id if (id != -1) { rc=shmctl(id, IPC_STAT, &shminfo); // get stats on it if (!rc) { if (shminfo.shm_nattch) { fprintf(stderr, "User %d appears to be running " "DOOM. Is that wise?\n", shminfo.shm_cpid); key++; } else { if (getuid() == shminfo.shm_perm.cuid) { rc = shmctl(id, IPC_RMID, 0); if (!rc) fprintf(stderr, "Was able to kill my old shared memory\n"); else I_Error("Was NOT able to kill my old shared memory"); id = shmget((key_t)key, size, IPC_CREAT|0777); if (id==-1) I_Error("Could not get shared memory"); rc=shmctl(id, IPC_STAT, &shminfo); break; } if (size >= shminfo.shm_segsz) { fprintf(stderr, "will use %d's stale shared memory\n", shminfo.shm_cpid); break; } else { fprintf(stderr, "warning: can't use stale " "shared memory belonging to id %d, " "key=0x%x\n", shminfo.shm_cpid, key); key++; } } } else { I_Error("could not get stats on key=%d", key); } } else { id = shmget((key_t)key, size, IPC_CREAT|0777); if (id==-1) { extern int errno; fprintf(stderr, "errno=%d\n", errno); I_Error("Could not get any shared memory"); } break; } } while (--pollution); if (!pollution) { I_Error("Sorry, system too polluted with stale " "shared memory segments.\n"); } X_shminfo.shmid = id; // attach to the shared memory segment image->data = X_shminfo.shmaddr = shmat(id, 0, 0); if(verbose) { fprintf(stderr, "shared memory id=%d, addr=0x%x\n", id, (int) (image->data)); } return;}// return number of fullscreen + X11 modesint VID_NumModes(void) { if(haveVoodoo) return NUM_VOODOOMODES; else if(cv_fullscreen.value && vidmode_ext) return num_vidmodes; else return MAXWINMODES;}char *VID_GetModeName(int modenum) { static boolean displayWarning = true; // display a warning message if no lores modes are available under fullscreen if(displayWarning && cv_fullscreen.value && vidmode_ext && !haveVoodoo) { displayWarning = false; // do it only once if(vidmodes[vidmap[lowest_vidmode]]->hdisplay >= HIRES_HORIZ || vidmodes[vidmap[lowest_vidmode]]->vdisplay >= HIRES_VERT) { // violation of hierarchical structure; use callback function instead? M_StartMessage("You don't have lores modes\nin your XF86Config\n\nPlease read the FAQ\n",NULL,MM_NOTHING); } } if(haveVoodoo) { // voodoo modes if(modenum >= NUM_VOODOOMODES) return NULL; sprintf(&vidModeName[modenum][0], "fx %dx%d", voodooModes[modenum][0], voodooModes[modenum][1]); } else if(cv_fullscreen.value && vidmode_ext) { // fullscreen modes if(modenum >= num_vidmodes) return NULL; sprintf(&vidModeName[modenum][0], "%dx%d", vidmodes[vidmap[modenum]]->hdisplay, vidmodes[vidmap[modenum]]->vdisplay); } else { // X11 modes if(modenum > MAXWINMODES) return NULL; sprintf(&vidModeName[modenum][0], "X11 %dx%d", windowedModes[modenum][0], windowedModes[modenum][1]); } return &vidModeName[modenum][0];}int VID_GetModeForSize( int w, int h) { static boolean first_override=true; int best_fit, i; if(haveVoodoo) { best_fit = 1; // standard mode if no other found for (i = 0; i < NUM_VOODOOMODES; i++) { if (w == voodooModes[i][0] && h == voodooModes[i][1]) { best_fit = i; } } } // scan fullscreen modes else if(cv_fullscreen.value && vidmode_ext) { best_fit = -1; for (i = 0; i < num_vidmodes; i++) { if (w == vidmodes[vidmap[i]]->hdisplay && h == vidmodes[vidmap[i]]->vdisplay) { best_fit = i; } } // !!! first_override prevents switching to fullscreen is no lores modes are available and no matching mode is found at startup // any other valid mode (windowed, match) disables first_override not to prevent the user from switching if(best_fit == -1) { // no fitting vidmode found if(first_override) { // overwrite lowest_vidmode setting the first time if resolution too high first_override=false; if(vidmodes[vidmap[lowest_vidmode]]->hdisplay * vidmodes[vidmap[lowest_vidmode]]->vdisplay < HIRES_HORIZ*HIRES_VERT) { best_fit = lowest_vidmode; // use lowest fullscreen mode if it is not too hires } else { // if lowest fullscreen mode is too hires use lowest windowed mode CV_SetValue(&cv_fullscreen, 0); VID_PrepareModeList(); best_fit = MAXWINMODES-1; } } else { best_fit = lowest_vidmode; } } else if(first_override) first_override = false; // disable first_override } else { // windowed modes best_fit = MAXWINMODES-1; if(first_override) first_override = false; // disable first_override for (i = 0; i < MAXWINMODES; i++) { if (w == windowedModes[i][0] && h == windowedModes[i][1]) { best_fit = i; } } } return best_fit ;}static void destroyWindow(void){ doUngrabMouse(); if(rendermode==render_soft) { if( vid.buffer ) { free(vid.buffer); vid.buffer = vid.direct = screens[0] = NULL; // I want to have an access violation if something goes wrong } if(doShm) { if (!XShmDetach(X_display, &X_shminfo)) I_Error("XShmDetach() failed in destroyWindow()"); // Release shared memory.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -