📄 sdl_x11video.c
字号:
if(i == this->hidden->nvisuals) { /* default visual was useless, take the deepest one instead */ i = 0; } SDL_Visual = this->hidden->visuals[i].visual; if ( SDL_Visual == DefaultVisual(SDL_Display, SDL_Screen) ) { SDL_XColorMap = SDL_DisplayColormap; } else { SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root, SDL_Visual, AllocNone); } this->hidden->depth = this->hidden->visuals[i].depth; vformat->BitsPerPixel = this->hidden->visuals[i].bpp; if ( vformat->BitsPerPixel > 8 ) { vformat->Rmask = SDL_Visual->red_mask; vformat->Gmask = SDL_Visual->green_mask; vformat->Bmask = SDL_Visual->blue_mask; } X11_SaveVidModeGamma(this); /* See if we have been passed a window to use */ SDL_windowid = getenv("SDL_WINDOWID"); /* Create the fullscreen and managed windows */ create_aux_windows(this); /* Create the blank cursor */ SDL_BlankCursor = this->CreateWMCursor(this, blank_cdata, blank_cmask, BLANK_CWIDTH, BLANK_CHEIGHT, BLANK_CHOTX, BLANK_CHOTY); /* Fill in some window manager capabilities */ this->info.wm_available = 1; /* We're done! */ XFlush(SDL_Display); return(0);}static void X11_DestroyWindow(_THIS, SDL_Surface *screen){ /* Clean up OpenGL */ if ( screen ) { screen->flags &= ~(SDL_OPENGL|SDL_OPENGLBLIT); } X11_GL_Shutdown(this); if ( ! SDL_windowid ) { /* Hide the managed window */ if ( WMwindow ) { XUnmapWindow(SDL_Display, WMwindow); } if ( screen && (screen->flags & SDL_FULLSCREEN) ) { screen->flags &= ~SDL_FULLSCREEN; X11_LeaveFullScreen(this); } /* Destroy the output window */ if ( SDL_Window ) { XDestroyWindow(SDL_Display, SDL_Window); } /* Free the colormap entries */ if ( SDL_XPixels ) { int numcolors; unsigned long pixel; numcolors = SDL_Visual->map_entries; for ( pixel=0; pixel<numcolors; ++pixel ) { while ( SDL_XPixels[pixel] > 0 ) { XFreeColors(GFX_Display, SDL_DisplayColormap,&pixel,1,0); --SDL_XPixels[pixel]; } } free(SDL_XPixels); SDL_XPixels = NULL; } /* Free the graphics context */ if ( SDL_GC ) { XFreeGC(SDL_Display, SDL_GC); SDL_GC = 0; } }}static SDL_bool X11_WindowPosition(_THIS, int *x, int *y, int w, int h){ const char *window = getenv("SDL_VIDEO_WINDOW_POS"); const char *center = getenv("SDL_VIDEO_CENTERED"); if ( window ) { if ( sscanf(window, "%d,%d", x, y) == 2 ) { return SDL_TRUE; } if ( strcmp(window, "center") == 0 ) { center = window; } } if ( center ) { *x = (DisplayWidth(SDL_Display, SDL_Screen) - w)/2; *y = (DisplayHeight(SDL_Display, SDL_Screen) - h)/2; return SDL_TRUE; } return SDL_FALSE;}static void X11_SetSizeHints(_THIS, int w, int h, Uint32 flags){ XSizeHints *hints; hints = XAllocSizeHints(); if ( hints ) { if ( flags & SDL_RESIZABLE ) { hints->min_width = 32; hints->min_height = 32; hints->max_height = 4096; hints->max_width = 4096; } else { hints->min_width = hints->max_width = w; hints->min_height = hints->max_height = h; } hints->flags = PMaxSize | PMinSize; if ( flags & SDL_FULLSCREEN ) { hints->x = 0; hints->y = 0; hints->flags |= USPosition; } else /* Center it, if desired */ if ( X11_WindowPosition(this, &hints->x, &hints->y, w, h) ) { hints->flags |= USPosition; XMoveWindow(SDL_Display, WMwindow, hints->x, hints->y); /* Flush the resize event so we don't catch it later */ XSync(SDL_Display, True); } XSetWMNormalHints(SDL_Display, WMwindow, hints); XFree(hints); } /* Respect the window caption style */ if ( flags & SDL_NOFRAME ) { SDL_bool set; Atom WM_HINTS; /* We haven't modified the window manager hints yet */ set = SDL_FALSE; /* First try to set MWM hints */ WM_HINTS = XInternAtom(SDL_Display, "_MOTIF_WM_HINTS", True); if ( WM_HINTS != None ) { /* Hints used by Motif compliant window managers */ struct { unsigned long flags; unsigned long functions; unsigned long decorations; long input_mode; unsigned long status; } MWMHints = { (1L << 1), 0, 0, 0, 0 }; XChangeProperty(SDL_Display, WMwindow, WM_HINTS, WM_HINTS, 32, PropModeReplace, (unsigned char *)&MWMHints, sizeof(MWMHints)/sizeof(long)); set = SDL_TRUE; } /* Now try to set KWM hints */ WM_HINTS = XInternAtom(SDL_Display, "KWM_WIN_DECORATION", True); if ( WM_HINTS != None ) { long KWMHints = 0; XChangeProperty(SDL_Display, WMwindow, WM_HINTS, WM_HINTS, 32, PropModeReplace, (unsigned char *)&KWMHints, sizeof(KWMHints)/sizeof(long)); set = SDL_TRUE; } /* Now try to set GNOME hints */ WM_HINTS = XInternAtom(SDL_Display, "_WIN_HINTS", True); if ( WM_HINTS != None ) { long GNOMEHints = 0; XChangeProperty(SDL_Display, WMwindow, WM_HINTS, WM_HINTS, 32, PropModeReplace, (unsigned char *)&GNOMEHints, sizeof(GNOMEHints)/sizeof(long)); set = SDL_TRUE; } /* Finally set the transient hints if necessary */ if ( ! set ) { XSetTransientForHint(SDL_Display, WMwindow, SDL_Root); } } else { SDL_bool set; Atom WM_HINTS; /* We haven't modified the window manager hints yet */ set = SDL_FALSE; /* First try to unset MWM hints */ WM_HINTS = XInternAtom(SDL_Display, "_MOTIF_WM_HINTS", True); if ( WM_HINTS != None ) { XDeleteProperty(SDL_Display, WMwindow, WM_HINTS); set = SDL_TRUE; } /* Now try to unset KWM hints */ WM_HINTS = XInternAtom(SDL_Display, "KWM_WIN_DECORATION", True); if ( WM_HINTS != None ) { XDeleteProperty(SDL_Display, WMwindow, WM_HINTS); set = SDL_TRUE; } /* Now try to unset GNOME hints */ WM_HINTS = XInternAtom(SDL_Display, "_WIN_HINTS", True); if ( WM_HINTS != None ) { XDeleteProperty(SDL_Display, WMwindow, WM_HINTS); set = SDL_TRUE; } /* Finally unset the transient hints if necessary */ if ( ! set ) { /* NOTE: Does this work? */ XSetTransientForHint(SDL_Display, WMwindow, None); } }}static int X11_CreateWindow(_THIS, SDL_Surface *screen, int w, int h, int bpp, Uint32 flags){ int i, depth; Visual *vis; int vis_change; /* If a window is already present, destroy it and start fresh */ if ( SDL_Window ) { X11_DestroyWindow(this, screen); } /* See if we have been given a window id */ if ( SDL_windowid ) { SDL_Window = strtol(SDL_windowid, NULL, 0); } else { SDL_Window = 0; } /* find out which visual we are going to use */ if ( flags & SDL_OPENGL ) { XVisualInfo *vi; vi = X11_GL_GetVisual(this); if( !vi ) { return -1; } vis = vi->visual; depth = vi->depth; } else if ( SDL_windowid ) { XWindowAttributes a; XGetWindowAttributes(SDL_Display, SDL_Window, &a); vis = a.visual; depth = a.depth; } else { for ( i = 0; i < this->hidden->nvisuals; i++ ) { if ( this->hidden->visuals[i].bpp == bpp ) break; } if ( i == this->hidden->nvisuals ) { SDL_SetError("No matching visual for requested depth"); return -1; /* should never happen */ } vis = this->hidden->visuals[i].visual; depth = this->hidden->visuals[i].depth; }#ifdef X11_DEBUG printf("Choosing %s visual at %d bpp - %d colormap entries\n", vis->class == PseudoColor ? "PseudoColor" : (vis->class == TrueColor ? "TrueColor" : (vis->class == DirectColor ? "DirectColor" : "Unknown")), depth, vis->map_entries);#endif vis_change = (vis != SDL_Visual); SDL_Visual = vis; this->hidden->depth = depth; /* Allocate the new pixel format for this video mode */ if ( ! SDL_ReallocFormat(screen, bpp, vis->red_mask, vis->green_mask, vis->blue_mask, 0) ) return -1; /* Create the appropriate colormap */ if ( SDL_XColorMap != SDL_DisplayColormap ) { XFreeColormap(SDL_Display, SDL_XColorMap); } if ( SDL_Visual->class == PseudoColor ) { int ncolors; /* Allocate the pixel flags */ ncolors = SDL_Visual->map_entries; SDL_XPixels = malloc(ncolors * sizeof(int)); if(SDL_XPixels == NULL) { SDL_OutOfMemory(); return -1; } memset(SDL_XPixels, 0, ncolors * sizeof(*SDL_XPixels)); /* always allocate a private colormap on non-default visuals */ if ( SDL_Visual != DefaultVisual(SDL_Display, SDL_Screen) ) { flags |= SDL_HWPALETTE; } if ( flags & SDL_HWPALETTE ) { screen->flags |= SDL_HWPALETTE; SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root, SDL_Visual, AllocAll); } else { SDL_XColorMap = SDL_DisplayColormap; } } else if ( SDL_Visual->class == DirectColor ) { /* Create a colormap which we can manipulate for gamma */ SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root, SDL_Visual, AllocAll); XSync(SDL_Display, False); /* Initialize the colormap to the identity mapping */ SDL_GetGammaRamp(0, 0, 0); this->screen = screen; X11_SetGammaRamp(this, this->gamma); this->screen = NULL; } else { /* Create a read-only colormap for our window */ SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root, SDL_Visual, AllocNone); } /* Recreate the auxiliary windows, if needed (required for GL) */ if ( vis_change ) create_aux_windows(this); if(screen->flags & SDL_HWPALETTE) { /* Since the full-screen window might have got a nonzero background colour (0 is white on some displays), we should reset the background to 0 here since that is what the user expects with a private colormap */ XSetWindowBackground(SDL_Display, FSwindow, 0); XClearWindow(SDL_Display, FSwindow); } /* resize the (possibly new) window manager window */ if( !SDL_windowid ) { X11_SetSizeHints(this, w, h, flags); current_w = w; current_h = h; XResizeWindow(SDL_Display, WMwindow, w, h); } /* Create (or use) the X11 display window */ if ( !SDL_windowid ) { if ( flags & SDL_OPENGL ) { if ( X11_GL_CreateWindow(this, w, h) < 0 ) { return(-1); } } else { XSetWindowAttributes swa; swa.background_pixel = 0; swa.border_pixel = 0; swa.colormap = SDL_XColorMap; SDL_Window = XCreateWindow(SDL_Display, WMwindow, 0, 0, w, h, 0, depth, InputOutput, SDL_Visual, CWBackPixel | CWBorderPixel | CWColormap, &swa); } /* Only manage our input if we own the window */ XSelectInput(SDL_Display, SDL_Window, ( EnterWindowMask | LeaveWindowMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | ExposureMask )); } /* Create the graphics context here, once we have a window */ if ( flags & SDL_OPENGL ) { if ( X11_GL_CreateContext(this) < 0 ) { return(-1); } else { screen->flags |= SDL_OPENGL; } } else { XGCValues gcv; gcv.graphics_exposures = False; SDL_GC = XCreateGC(SDL_Display, SDL_Window, GCGraphicsExposures, &gcv); if ( ! SDL_GC ) { SDL_SetError("Couldn't create graphics context"); return(-1); } } /* Set our colormaps when not setting a GL mode */ if ( ! (flags & SDL_OPENGL) ) { XSetWindowColormap(SDL_Display, SDL_Window, SDL_XColorMap); if( !SDL_windowid ) { XSetWindowColormap(SDL_Display, FSwindow, SDL_XColorMap); XSetWindowColormap(SDL_Display, WMwindow, SDL_XColorMap); } }#if 0 /* This is an experiment - are the graphics faster now? - nope. */ if ( getenv("SDL_VIDEO_X11_BACKINGSTORE") )#endif /* Cache the window in the server, when possible */ { Screen *xscreen; XSetWindowAttributes a; xscreen = ScreenOfDisplay(SDL_Display, SDL_Screen); a.backing_store = DoesBackingStore(xscreen); if ( a.backing_store != NotUseful ) { XChangeWindowAttributes(SDL_Display, SDL_Window, CWBackingStore, &a); } } /* Update the internal keyboard state */ X11_SetKeyboardState(SDL_Display, NULL); /* When the window is first mapped, ignore non-modifier keys */ { Uint8 *keys = SDL_GetKeyState(NULL); for ( i = 0; i < SDLK_LAST; ++i ) { switch (i) { case SDLK_NUMLOCK:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -