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;
}
Exemple #2
0
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);
}