NestedClientPrivatePtr NestedClientCreateScreen(int scrnIndex, Bool wantFullscreenHint, unsigned int width, unsigned int height, int originX, int originY, unsigned int depth, unsigned int bitsPerPixel, Pixel *retRedMask, Pixel *retGreenMask, Pixel *retBlueMask) { NestedClientPrivatePtr pPriv; XSizeHints sizeHints; Bool supported; char windowTitle[32]; pPriv = malloc(sizeof(struct NestedClientPrivate)); pPriv->scrnIndex = scrnIndex; /* Needed until we can pass authorization file * directly to XOpenDisplay() */ if (xauthFile != NULL) setenv("XAUTHORITY", xauthFile, 1); pPriv->display = XOpenDisplay(NULL); if (!pPriv->display) return NULL; #ifdef NESTED_INPUT supported = XkbQueryExtension(pPriv->display, &pPriv->xkb.op, &pPriv->xkb.event, &pPriv->xkb.error, &pPriv->xkb.major, &pPriv->xkb.minor); if (!supported) { xf86DrvMsg(pPriv->scrnIndex, X_ERROR, "The remote server does not support the XKEYBOARD extension.\n"); XCloseDisplay(pPriv->display); return NULL; } #endif pPriv->screenNumber = DefaultScreen(pPriv->display); pPriv->screen = ScreenOfDisplay(pPriv->display, pPriv->screenNumber); pPriv->rootWindow = RootWindow(pPriv->display, pPriv->screenNumber); pPriv->gc = DefaultGC(pPriv->display, pPriv->screenNumber); pPriv->window = XCreateSimpleWindow(pPriv->display, pPriv->rootWindow, originX, originY, width, height, 0, 0, 0); sizeHints.flags = PPosition | PSize | PMinSize | PMaxSize; sizeHints.min_width = width; sizeHints.max_width = width; sizeHints.min_height = height; sizeHints.max_height = height; XSetWMNormalHints(pPriv->display, pPriv->window, &sizeHints); snprintf(windowTitle, sizeof(windowTitle), "Screen %d", scrnIndex); XStoreName(pPriv->display, pPriv->window, windowTitle); XMapWindow(pPriv->display, pPriv->window); XSelectInput(pPriv->display, pPriv->window, #ifdef NESTED_INPUT PointerMotionMask | EnterWindowMask | LeaveWindowMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | #endif ExposureMask); if (!NestedClientTryXShm(pPriv, scrnIndex, width, height, depth)) { pPriv->img = XCreateImage(pPriv->display, DefaultVisualOfScreen(pPriv->screen), depth, ZPixmap, 0, /* offset */ NULL, /* data */ width, height, 32, /* XXX: bitmap_pad */ 0 /* XXX: bytes_per_line */); if (!pPriv->img) return NULL; pPriv->img->data = malloc(pPriv->img->bytes_per_line * pPriv->img->height); pPriv->usingShm = FALSE; } if (!pPriv->img->data) return NULL; NestedClientHideCursor(pPriv); /* Hide cursor */ #if 0 xf86DrvMsg(scrnIndex, X_INFO, "width: %d\n", pPriv->img->width); xf86DrvMsg(scrnIndex, X_INFO, "height: %d\n", pPriv->img->height); xf86DrvMsg(scrnIndex, X_INFO, "xoffset: %d\n", pPriv->img->xoffset); xf86DrvMsg(scrnIndex, X_INFO, "depth: %d\n", pPriv->img->depth); xf86DrvMsg(scrnIndex, X_INFO, "bpp: %d\n", pPriv->img->bits_per_pixel); xf86DrvMsg(scrnIndex, X_INFO, "red_mask: 0x%lx\n", pPriv->img->red_mask); xf86DrvMsg(scrnIndex, X_INFO, "gre_mask: 0x%lx\n", pPriv->img->green_mask); xf86DrvMsg(scrnIndex, X_INFO, "blu_mask: 0x%lx\n", pPriv->img->blue_mask); #endif *retRedMask = pPriv->img->red_mask; *retGreenMask = pPriv->img->green_mask; *retBlueMask = pPriv->img->blue_mask; XEvent ev; while (1) { XNextEvent(pPriv->display, &ev); if (ev.type == Expose) { break; } } pPriv->dev = (DeviceIntPtr)NULL; return pPriv; }
void S9xInitDisplay (int argc, char **argv) { GUI.display = XOpenDisplay(NULL); if (GUI.display == NULL) FatalError("Failed to connect to X server."); GUI.screen = DefaultScreenOfDisplay(GUI.display); GUI.screen_num = XScreenNumberOfScreen(GUI.screen); GUI.visual = DefaultVisualOfScreen(GUI.screen); XVisualInfo plate, *matches; int count; plate.visualid = XVisualIDFromVisual(GUI.visual); matches = XGetVisualInfo(GUI.display, VisualIDMask, &plate, &count); if (!count) FatalError("Your X Window System server is unwell!"); GUI.depth = matches[0].depth; if ((GUI.depth != 15 && GUI.depth != 16 && GUI.depth != 24) || (matches[0].c_class != TrueColor)) FatalError("Requiers 15, 16, 24 or 32-bit color depth supporting TrueColor."); GUI.red_shift = ffs(matches[0].red_mask) - 1; GUI.green_shift = ffs(matches[0].green_mask) - 1; GUI.blue_shift = ffs(matches[0].blue_mask) - 1; GUI.red_size = matches[0].red_mask >> GUI.red_shift; GUI.green_size = matches[0].green_mask >> GUI.green_shift; GUI.blue_size = matches[0].blue_mask >> GUI.blue_shift; if (GUI.depth == 16 && GUI.green_size == 63) GUI.green_shift++; XFree(matches); switch (GUI.depth) { default: case 32: case 24: S9xSetRenderPixelFormat(RGB555); GUI.pixel_format = 555; break; case 16: if (GUI.red_size != GUI.green_size || GUI.blue_size != GUI.green_size) { // 565 format if (GUI.green_shift > GUI.blue_shift && GUI.green_shift > GUI.red_shift) S9xSetRenderPixelFormat(GBR565); else if (GUI.red_shift > GUI.blue_shift) S9xSetRenderPixelFormat(RGB565); else S9xSetRenderPixelFormat(BGR565); GUI.pixel_format = 565; break; } // FALL ... case 15: if (GUI.green_shift > GUI.blue_shift && GUI.green_shift > GUI.red_shift) S9xSetRenderPixelFormat(GBR555); else if (GUI.red_shift > GUI.blue_shift) S9xSetRenderPixelFormat(RGB555); else S9xSetRenderPixelFormat(BGR555); GUI.pixel_format = 555; break; } S9xBlitFilterInit(); S9xBlit2xSaIFilterInit(); S9xBlitHQ2xFilterInit(); XSetWindowAttributes attrib; memset(&attrib, 0, sizeof(attrib)); attrib.background_pixel = BlackPixelOfScreen(GUI.screen); attrib.colormap = XCreateColormap(GUI.display, RootWindowOfScreen(GUI.screen), GUI.visual, AllocNone); GUI.window = XCreateWindow(GUI.display, RootWindowOfScreen(GUI.screen), (WidthOfScreen(GUI.screen) - SNES_WIDTH * 2) / 2, (HeightOfScreen(GUI.screen) - SNES_HEIGHT_EXTENDED * 2) / 2, SNES_WIDTH * 2, SNES_HEIGHT_EXTENDED * 2, 0, GUI.depth, InputOutput, GUI.visual, CWBackPixel | CWColormap, &attrib); static XColor bg, fg; static char data[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; Pixmap bitmap; bitmap = XCreateBitmapFromData(GUI.display, GUI.window, data, 8, 8); GUI.point_cursor = XCreatePixmapCursor(GUI.display, bitmap, bitmap, &fg, &bg, 0, 0); XDefineCursor(GUI.display, GUI.window, GUI.point_cursor); GUI.cross_hair_cursor = XCreateFontCursor(GUI.display, XC_crosshair); GUI.gc = DefaultGCOfScreen(GUI.screen); XSizeHints Hints; XWMHints WMHints; memset((void *) &Hints, 0, sizeof(XSizeHints)); memset((void *) &WMHints, 0, sizeof(XWMHints)); Hints.flags = PSize | PMinSize | PMaxSize; Hints.min_width = Hints.max_width = Hints.base_width = SNES_WIDTH * 2; Hints.min_height = Hints.max_height = Hints.base_height = SNES_HEIGHT_EXTENDED * 2; WMHints.input = True; WMHints.flags = InputHint; XSetWMHints(GUI.display, GUI.window, &WMHints); XSetWMNormalHints(GUI.display, GUI.window, &Hints); XSelectInput(GUI.display, GUI.window, FocusChangeMask | ExposureMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask | ButtonPressMask | ButtonReleaseMask); XMapRaised(GUI.display, GUI.window); XClearWindow(GUI.display, GUI.window); SetupImage(); switch (GUI.depth) { default: case 32: GUI.bytes_per_pixel = 4; break; case 24: if (GUI.image->bits_per_pixel == 24) GUI.bytes_per_pixel = 3; else GUI.bytes_per_pixel = 4; break; case 15: case 16: GUI.bytes_per_pixel = 2; break; } wmDeleteMessage = XInternAtom(GUI.display, "WM_DELETE_WINDOW", false); XSetWMProtocols(GUI.display, GUI.window, &wmDeleteMessage, 1); }