/*!***********************************************************************
 @Function		OpenX11Window
 @Return		true on success
 @Description	Opens an X11 window. This must be called after
				SelectEGLConfiguration() for gEglConfig to be valid
*************************************************************************/
int PVRShellInitOS::OpenX11Window(const PVRShell &shell)
{
    XSetWindowAttributes	WinAttibutes;
    XSizeHints				sh;
    XEvent					event;
    unsigned long			mask;

#ifdef BUILD_OGL
    XF86VidModeModeInfo **modes;       // modes of display
    int numModes;                      // number of modes of display
    int chosenMode;
    int edimx,edimy;                   //established width and height of the chosen modeline
    int i;
#endif

	int depth = DefaultDepth(m_X11Display, m_X11Screen);
	m_X11Visual = new XVisualInfo;
	XMatchVisualInfo( m_X11Display, m_X11Screen, depth, TrueColor, m_X11Visual);

    if( !m_X11Visual )
    {
    	shell.PVRShellOutputDebug( "Unable to acquire visual" );
    	return false;
    }

    m_X11ColorMap = XCreateColormap( m_X11Display, RootWindow(m_X11Display, m_X11Screen), m_X11Visual->visual, AllocNone );

#ifdef BUILD_OGL
    m_i32OriginalModeDotClock = XF86VidModeBadClock;
    if(shell.m_pShellData->bFullScreen)
    {
        // Get mode lines to see if there is requested modeline
        XF86VidModeGetAllModeLines(m_X11Display, m_X11Screen, &numModes, &modes);

        // look for mode with requested resolution
        chosenMode = -1;
        i=0;
        while((chosenMode == -1)&&(i<numModes))
        {
            if ((modes[i]->hdisplay == shell.m_pShellData->nShellDimX) && (modes[i]->vdisplay == shell.m_pShellData->nShellDimY))
            {
                chosenMode = i;
            }
            ++i;
        }

        // If there is no requested resolution among modelines then terminate
        if(chosenMode == -1)
        {
            shell.PVRShellOutputDebug( "Chosen resolution for full screen mode does not match any modeline available.\n" );
            return false;
        }

        // save desktop-resolution before switching modes
        XF86VidModeGetModeLine(m_X11Display,m_X11Screen, &m_i32OriginalModeDotClock, &m_OriginalMode );

        XF86VidModeSwitchToMode(m_X11Display, m_X11Screen, modes[chosenMode]);
        XF86VidModeSetViewPort(m_X11Display, m_X11Screen, 0, 0);
        edimx = modes[chosenMode]->hdisplay;
        edimy = modes[chosenMode]->vdisplay;
        printf("Fullscreen Resolution %dx%d (chosen mode = %d)\n", edimx, edimy,chosenMode);
        XFree(modes);

		WinAttibutes.colormap = m_X11ColorMap;
		WinAttibutes.background_pixel = 0xFFFFFFFF;
		WinAttibutes.border_pixel = 0;
        WinAttibutes.override_redirect = true;

		// add to these for handling other events
		WinAttibutes.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | Button1MotionMask | KeyPressMask | KeyReleaseMask;

        // The diffrence is that we want to ignore influence of window manager for our fullscreen window
        mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap | CWOverrideRedirect;

        m_X11Window = XCreateWindow( m_X11Display, RootWindow(m_X11Display, m_X11Screen), 0, 0, edimx, edimy, 0,
                                    CopyFromParent, InputOutput, CopyFromParent, mask, &WinAttibutes);

        // keeping the pointer of mouse and keyboard in window to prevent from scrolling the virtual screen
        XWarpPointer(m_X11Display, None ,m_X11Window, 0, 0, 0, 0, 0, 0);

        // Map and then wait till mapped, grabbing should be after mapping the window
        XMapWindow( m_X11Display, m_X11Window );
        XGrabKeyboard(m_X11Display, m_X11Window, True, GrabModeAsync, GrabModeAsync, CurrentTime);
        XGrabPointer(m_X11Display, m_X11Window, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, m_X11Window, None, CurrentTime);
        XIfEvent( m_X11Display, &event, WaitForMapNotify, (char*)m_X11Window );

    }
    else
#endif
    {
        // For OGLES we assume that chaning of video mode is not available (freedesktop does not allow to do it)
        // so if requested resolution differs from the display dims then we quit
        #ifndef BUILD_OGL
        int display_width  = XDisplayWidth(m_X11Display,m_X11Screen);
        int display_height = XDisplayHeight(m_X11Display,m_X11Screen);
        if((shell.m_pShellData->bFullScreen)&&((shell.m_pShellData->nShellDimX != display_width)||(shell.m_pShellData->nShellDimY != display_height)) ) {
            shell.PVRShellOutputDebug( "Chosen resolution for full screen mode does not match available modeline.\n" );
            return false;
        }
        #endif


		WinAttibutes.colormap = m_X11ColorMap;
		WinAttibutes.background_pixel = 0xFFFFFFFF;
		WinAttibutes.border_pixel = 0;

		// add to these for handling other events
		WinAttibutes.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | Button1MotionMask | KeyPressMask | KeyReleaseMask;

		// The attribute mask
        mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap ;

        m_X11Window = XCreateWindow(  m_X11Display, 						// Display
									RootWindow(m_X11Display, m_X11Screen), 	// Parent
									shell.m_pShellData->nShellPosX, 	// X position of window
									shell.m_pShellData->nShellPosY,		// Y position of window
									shell.m_pShellData->nShellDimX,		// Window width
									shell.m_pShellData->nShellDimY,		// Window height
									0,									// Border width
									CopyFromParent, 					// Depth (taken from parent)
									InputOutput, 						// Window class
									CopyFromParent, 					// Visual type (taken from parent)
									mask, 								// Attributes mask
									&WinAttibutes);						// Attributes

		// Set the window position
        sh.flags = USPosition;
        sh.x = shell.m_pShellData->nShellPosX;
        sh.y = shell.m_pShellData->nShellPosY;
        XSetStandardProperties( m_X11Display, m_X11Window, shell.m_pShellData->pszAppName, shell.m_pShellData->pszAppName, None, 0, 0, &sh );

        // Map and then wait till mapped
        XMapWindow( m_X11Display, m_X11Window );
        XIfEvent( m_X11Display, &event, WaitForMapNotify, (char*)m_X11Window );

        // An attempt to hide a border for fullscreen on non OGL apis (OGLES,OGLES2)
        if(shell.m_pShellData->bFullScreen)
        {
			XEvent xev;
			Atom wmState = XInternAtom(m_X11Display, "_NET_WM_STATE", False);
			Atom wmStateFullscreen = XInternAtom(m_X11Display, "_NET_WM_STATE_FULLSCREEN", False);

			memset(&xev, 0, sizeof(XEvent));
			xev.type = ClientMessage;
			xev.xclient.window = m_X11Window;
			xev.xclient.message_type = wmState;
			xev.xclient.format = 32;
			xev.xclient.data.l[0] = 1;
			xev.xclient.data.l[1] = wmStateFullscreen;
			xev.xclient.data.l[2] = 0;
			XSendEvent(m_X11Display, RootWindow(m_X11Display, m_X11Screen), False, SubstructureNotifyMask, &xev);
        }

        Atom wmDelete = XInternAtom(m_X11Display, "WM_DELETE_WINDOW", True);
        XSetWMProtocols(m_X11Display, m_X11Window, &wmDelete, 1);
        XSetWMColormapWindows( m_X11Display, m_X11Window, &m_X11Window, 1 );
    }

    XFlush( m_X11Display );

    return true;
}
Exemple #2
0
// needs to be run after SelectEGLConfiguration()
// for gEglConfig to be valid
int PVRShellInitOS::OpenX11Window(const PVRShell &shell)
{
    XSetWindowAttributes	wa;
    XSizeHints				sh;
    XEvent					event;
    unsigned long			mask;
    #ifdef BUILD_OGL
    XF86VidModeModeInfo **modes;       // modes of display
    int numModes;                      // number of modes of display
    int chosenMode;
    int edimx,edimy;                   //established width and height of the chosen modeline
    int i;
    #endif
    MyHints mwmhints;
    Atom prop;

	int depth = DefaultDepth(x11display, x11screen);
	x11visual = new XVisualInfo;
	XMatchVisualInfo( x11display, x11screen, depth, TrueColor, x11visual);

    if( !x11visual )
    {
    	shell.PVRShellOutputDebug( "Unable to acquire visual" );
    	return false;
    }

    x11colormap = XCreateColormap( x11display, RootWindow(x11display, x11screen), x11visual->visual, AllocNone );

    #ifdef BUILD_OGL
    originalMode_dotclock = XF86VidModeBadClock;
    if(shell.m_pShellData->bFullScreen) {

        // Get mode lines to see if there is requested modeline
        XF86VidModeGetAllModeLines(x11display, x11screen, &numModes, &modes);
        /* look for mode with requested resolution */
        chosenMode = -1;
        i=0;
        while((chosenMode == -1)&&(i<numModes))
        {
            if ((modes[i]->hdisplay == shell.m_pShellData->nShellDimX) && (modes[i]->vdisplay == shell.m_pShellData->nShellDimY))
            {
                chosenMode = i;
            }
            ++i;
        }

        // If there is no requested resolution among modelines then terminate
        if(chosenMode == -1)
        {
            shell.PVRShellOutputDebug( "Chosen resolution for full screen mode does not match any modeline available.\n" );
            return false;
        }

        /* save desktop-resolution before switching modes */
        XF86VidModeGetModeLine(x11display,x11screen, &originalMode_dotclock, &originalMode );

        XF86VidModeSwitchToMode(x11display, x11screen, modes[chosenMode]);
        XF86VidModeSetViewPort(x11display, x11screen, 0, 0);
        edimx = modes[chosenMode]->hdisplay;
        edimy = modes[chosenMode]->vdisplay;
        printf("Fullscreen Resolution %dx%d (chosen mode = %d)\n", edimx, edimy,chosenMode);
        XFree(modes);       //to musi byc globalne

        wa.colormap = x11colormap;
        wa.background_pixel = 0xFFFFFFFF;
        wa.border_pixel = 0;
        wa.override_redirect = true;

        // add to these for handling other events
        wa.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask;

        // The diffrence is that we want to ignore influence of window manager for outr fullscreen window
        mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap | CWOverrideRedirect;

        x11window = XCreateWindow( x11display, RootWindow(x11display, x11screen), 0, 0, edimx, edimy, 0,
                                    CopyFromParent, InputOutput, CopyFromParent, mask, &wa);
        // keeping the pointer of mouse and keyboard in window to prevent from scrolling the virtual screen
        XWarpPointer(x11display, None ,x11window, 0, 0, 0, 0, 0, 0);
        // Map and then wait till mapped, grabbing should be after mapping the window
        XMapWindow( x11display, x11window );
        XGrabKeyboard(x11display, x11window, True, GrabModeAsync, GrabModeAsync, CurrentTime);
        XGrabPointer(x11display, x11window, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, x11window, None, CurrentTime);
        XIfEvent( x11display, &event, WaitForMapNotify, (char*)x11window );

    } else {
    #endif
        wa.colormap = x11colormap;
        wa.background_pixel = 0xFFFFFFFF;
        wa.border_pixel = 0;

        // add to these for handling other events
        wa.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask;

        mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap ;

        x11window = XCreateWindow( x11display, RootWindow(x11display, x11screen), shell.m_pShellData->nShellPosX, shell.m_pShellData->nShellPosY,
                                    shell.m_pShellData->nShellDimX, shell.m_pShellData->nShellDimY, 0,
                                    CopyFromParent, InputOutput, CopyFromParent, mask, &wa);
        // todo:meh remove this?
        sh.flags = USPosition;
        sh.x = shell.m_pShellData->nShellPosX;
        sh.y = shell.m_pShellData->nShellPosY;
        XSetStandardProperties( x11display, x11window, szTitle, szTitle, None, 0, 0, &sh );
        // Map and then wait till mapped
        XMapWindow( x11display, x11window );
        XIfEvent( x11display, &event, WaitForMapNotify, (char*)x11window );
        // An attempt to hide a border for fullscreen on non OGL apis (OGLES,OGLES2)
        if(shell.m_pShellData->bFullScreen) {
            memset(&mwmhints, 0, sizeof(mwmhints));
            prop = XInternAtom(x11display, "_MOTIF_WM_HINTS", False);
            mwmhints.flags = 2;//MWM_HINTS_DECORATIONS;
            mwmhints.decorations = 0;
            XChangeProperty(x11display, x11window, prop, prop, 32, PropModeReplace,
            (unsigned char *) &mwmhints,5);
        }
        //
        Atom wmDelete = XInternAtom(x11display, "WM_DELETE_WINDOW", True);
        XSetWMProtocols(x11display, x11window, &wmDelete, 1);
        XSetWMColormapWindows( x11display, x11window, &x11window, 1 );
    #ifdef BUILD_OGL
    }
    #endif

    XFlush( x11display );

    return true;
}