Пример #1
0
static bool get_video_mode(Display *dpy, unsigned width, unsigned height, XF86VidModeModeInfo *mode, XF86VidModeModeInfo *desktop_mode)
{
   int i;
   int num_modes = 0;
   XF86VidModeModeInfo **modes = NULL;
   XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &num_modes, &modes);

   if (!num_modes)
   {
      XFree(modes);
      return false;
   }

   *desktop_mode = *modes[0];

   bool ret = false;
   for (i = 0; i < num_modes; i++)
   {
      if (modes[i]->hdisplay == width && modes[i]->vdisplay == height)
      {
         *mode = *modes[i];
         ret = true;
         break;
      }
   }

   XFree(modes);
   return ret;
}
Пример #2
0
GHOST_TSuccess
GHOST_DisplayManagerX11::
getNumDisplaySettings(
		GHOST_TUns8 display,
		GHOST_TInt32& numSettings) const
{
#ifdef WITH_X11_XF86VMODE
	int majorVersion, minorVersion;
	XF86VidModeModeInfo **vidmodes;
	Display *dpy = m_system->getXDisplay();

	GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");

	if (dpy == NULL)
		return GHOST_kFailure;

	majorVersion = minorVersion = 0;
	if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) {
		fprintf(stderr, "Error: XF86VidMode extension missing!\n");
		return GHOST_kFailure;
	}

	if (XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes)) {
		XFree(vidmodes);
	}

#else
	/* We only have one X11 setting at the moment. */
	GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
	numSettings = 1;
#endif

	return GHOST_kSuccess;
}
Пример #3
0
bool getAvailableDisplayModes(list<DisplayMode> * lstDisplayModes)
{
	Display * display;
	XF86VidModeModeInfo ** modes;
	int nbModes;

	display = XOpenDisplay(0);
	int screen = DefaultScreen(display);
	int bpp = XDefaultDepth(display, screen);
	XF86VidModeGetAllModeLines(display, screen, &nbModes, &modes);
	for (int i = 0; i < nbModes; i++) {
		// Check it's not already added
		bool skip = false;
		for (DisplayMode &mode : (*lstDisplayModes)) {
			if (mode.iWidth == modes[i]->hdisplay && mode.iHeight == modes[i]->vdisplay) {
				skip = true;
				break;
			}
		}
		if (!skip) {
			lstDisplayModes->push_back(DisplayMode(modes[i]->hdisplay, modes[i]->vdisplay, bpp));
		}
	}
	XFree(modes);
	return true;
}
Пример #4
0
// From ClanLib, LGPL (x11_resolution.cpp)
static XF86VidModeModeInfo GetXF86Mode(Display *dpy, int scr, int width, int height)
{
	XF86VidModeModeInfo **modes;
	XF86VidModeModeLine mode;
	int nmodes;
	int i;

	if ( XF86VidModeGetModeLine(dpy, scr, &i, &mode) &&
		XF86VidModeGetAllModeLines(dpy, scr, &nmodes, &modes))
	{
		qsort(modes, nmodes, sizeof *modes, cmpmodes);
		for (i=nmodes-1; i>= 0; --i) 
		{
			if ( (modes[i]->hdisplay >= width) &&
		             (modes[i]->vdisplay >= height) )
				break;
		}
		if (i>=0)
		{
			if ( (modes[i]->hdisplay != mode.hdisplay) ||
		             (modes[i]->vdisplay != mode.vdisplay) ) 
			{
				return *modes[i];
        		}
    	    		XFree(modes);
		}
	}
	
	XF86VidModeModeInfo dummy_mode;
	memset(&dummy_mode, 0, sizeof(dummy_mode));
	return dummy_mode;
}
Пример #5
0
/**
 *   fv_open_display: setup up X11, choose visual, create colomap and query fullscreen capabilities.
 */
int fv_open_display()
{
    char *display;

    fwl_thread_dump();

    /* Display */
    XInitThreads();

    display = getenv("DISPLAY");
    Xdpy = XOpenDisplay(display);
    if (!Xdpy) {
	ERROR_MSG("can't open display %s.\n", display);
	return FALSE;
    }

    /* start up a XLib error handler to catch issues with FreeWRL. There
       should not be any issues, but, if there are, we'll most likely just
       throw our hands up, and continue */
    XSetErrorHandler(fv_catch_XLIB); 

    Xscreen = DefaultScreen(Xdpy);
    Xroot_window = RootWindow(Xdpy,Xscreen);

    /* Visual */

    Xvi = fv_find_best_visual();
    if(!Xvi) { 
	    ERROR_MSG("FreeWRL can not find an appropriate visual from GLX\n");
	    return FALSE;
    }

    /* Fullscreen */

    if (fullscreen) {
#ifdef HAVE_XF86_VMODE
	    int i;
	    if (vmode_modes == NULL) {
		    if (XF86VidModeGetAllModeLines(Xdpy, Xscreen, &vmode_nb_modes, &vmode_modes) == 0) {
			    ERROR_MSG("can`t get mode lines through XF86VidModeGetAllModeLines.\n");
			    return FALSE;
		    }
		    qsort(vmode_modes, vmode_nb_modes, sizeof(XF86VidModeModeInfo*), mode_cmp);
	    }
	    for (i = 0; i < vmode_nb_modes; i++) {
		    if (vmode_modes[i]->hdisplay <= win_width && vmode_modes[i]->vdisplay <= win_height) {
			    fv_switch_to_mode(i);
			    break;
		    }
	    }
#endif
    }


    /* Color map */
    fv_create_colormap();

    return TRUE;
}
Пример #6
0
void X11DRV_XF86VM_Init(void)
{
  Bool ok;
  int nmodes;
  unsigned int i;

  if (xf86vm_major) return; /* already initialized? */

  /* see if XVidMode is available */
  wine_tsx11_lock();
  ok = XF86VidModeQueryExtension(gdi_display, &xf86vm_event, &xf86vm_error);
  if (ok)
  {
      X11DRV_expect_error(gdi_display, XVidModeErrorHandler, NULL);
      ok = XF86VidModeQueryVersion(gdi_display, &xf86vm_major, &xf86vm_minor);
      if (X11DRV_check_error()) ok = FALSE;
  }
  if (ok)
  {
#ifdef X_XF86VidModeSetGammaRamp
      if (xf86vm_major > 2 || (xf86vm_major == 2 && xf86vm_minor >= 1))
      {
          XF86VidModeGetGammaRampSize(gdi_display, DefaultScreen(gdi_display),
                                      &xf86vm_gammaramp_size);
          if (xf86vm_gammaramp_size == 256)
              xf86vm_use_gammaramp = TRUE;
      }
#endif /* X_XF86VidModeSetGammaRamp */

      /* retrieve modes */
      if (usexvidmode && root_window == DefaultRootWindow( gdi_display ))
          ok = XF86VidModeGetAllModeLines(gdi_display, DefaultScreen(gdi_display), &nmodes, &real_xf86vm_modes);
      else
          ok = FALSE; /* In desktop mode, do not switch resolution... But still use the Gamma ramp stuff */
  }
  wine_tsx11_unlock();
  if (!ok) return;

  TRACE("XVidMode modes: count=%d\n", nmodes);

  real_xf86vm_mode_count = nmodes;

  dd_modes = X11DRV_Settings_SetHandlers("XF86VidMode", 
                                         X11DRV_XF86VM_GetCurrentMode, 
                                         X11DRV_XF86VM_SetCurrentMode, 
                                         nmodes, 1);

  /* convert modes to DDHALMODEINFO format */
  for (i=0; i<real_xf86vm_mode_count; i++)
  {
      convert_modeinfo(real_xf86vm_modes[i]);
  }
  /* add modes for different color depths */
  X11DRV_Settings_AddDepthModes();
  dd_mode_count = X11DRV_Settings_GetModeCount();

  TRACE("Available DD modes: count=%d\n", dd_mode_count);
  TRACE("Enabling XVidMode\n");
}
Пример #7
0
gboolean xmms_fullscreen_init(GtkWidget * win)
{
	int event_base, error_base, dummy;
	fullscreen_window_t *fwin;
	gint i;
	XF86VidModeModeLine origmode;

	FULL_LOCK();
	fwin = getwindow(win);

	if (!XF86VidModeQueryExtension
	    (fwin->display->display, &event_base, &error_base))
	{
		FULL_UNLOCK();
		return FALSE;
	}

	if (!fwin->display->modes)
	{
		XF86VidModeGetAllModeLines(fwin->display->display,
					   DefaultScreen(fwin->display->display),
					   &fwin->display->num_modes,
					   &fwin->display->modes);

		if (!fwin->display->origmode)
		{
			XF86VidModeGetModeLine(fwin->display->display,
					       DefaultScreen(fwin->display->display),
					       &dummy, &origmode);
			for (i = 0; i < fwin->display->num_modes; i++)
			{
				if (fwin->display->modes[i]->hdisplay ==
				    origmode.hdisplay
				    && fwin->display->modes[i]->vdisplay ==
				    origmode.vdisplay)
				{
					fwin->display->origmode =
						fwin->display->modes[i];
					break;
				}
			}

			if (!fwin->display->origmode)
			{
				fprintf(stderr,
					"ERROR: Could not determine original mode.\n");
				FULL_UNLOCK();
				return FALSE;
			}

		}

		fwin->display->can_full = (fwin->display->num_modes > 1);
	}
	FULL_UNLOCK();
	return fwin->display->can_full;
}
GHOST_TSuccess
GHOST_DisplayManagerX11::
getDisplaySetting(
		GHOST_TUns8 display,
		GHOST_TInt32 index,
		GHOST_DisplaySetting& setting) const
{
	Display *dpy = m_system->getXDisplay();

	if (dpy == NULL)
		return GHOST_kFailure;

	(void)display;

#ifdef WITH_X11_XF86VMODE
	int majorVersion, minorVersion;

	GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");

	majorVersion = minorVersion = 0;
	if (XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) {
		XF86VidModeModeInfo **vidmodes;
		int numSettings;

		if (XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes)) {
			GHOST_ASSERT(index < numSettings, "Requested setting outside of valid range.\n");

			setting.xPixels = vidmodes[index]->hdisplay;
			setting.yPixels = vidmodes[index]->vdisplay;
			setting.bpp = DefaultDepth(dpy, DefaultScreen(dpy));
			setting.frequency = calculate_rate(vidmodes[index]);
			XFree(vidmodes);

			return GHOST_kSuccess;
		}
	}
	else {
		fprintf(stderr, "Warning: XF86VidMode extension missing!\n");
		/* fallback to non xf86vmode below */
	}
#endif  /* WITH_X11_XF86VMODE */

	GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
	GHOST_ASSERT(index < 1, "Requested setting outside of valid range.\n");
	(void)index;

	setting.xPixels  = DisplayWidth(dpy, DefaultScreen(dpy));
	setting.yPixels = DisplayHeight(dpy, DefaultScreen(dpy));
	setting.bpp = DefaultDepth(dpy, DefaultScreen(dpy));
	setting.frequency = 60.0f;

	return GHOST_kSuccess;
}
Пример #9
0
gboolean xmms_fullscreen_available(Display * dpy)
{
	int event_base, error_base, num_modes;
	XF86VidModeModeInfo **dummy;

	if (!XF86VidModeQueryExtension(dpy, &event_base, &error_base))
		return FALSE;

	XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &num_modes, &dummy);
	XFree(dummy);

	return (num_modes > 1);
}
Пример #10
0
static bool GetModes(Resolution **_modes, bool fullscreen)
{
	MFCALLSTACK;

	int numModeLines;

	if(!fullscreen)
	{
		modes = defaultModes;

		for(uint32 i = 0; modes[i].width != 0; ++i)
		{
			++numModes;
		}
	}
	else
	{
		int throwaway;
		if(!XF86VidModeQueryExtension(xdisplay, &throwaway, &throwaway))
		{
			SetSingleMode(_modes);
			return true;
		}

		if((!XF86VidModeGetAllModeLines(xdisplay, screen, &numModeLines, &vidModes)) || numModeLines < 2)
		{
			SetSingleMode(_modes);
			return true;
		}

		originalVidMode = vidModes[0];
		numModes = (uint32)numModeLines;

		modes = (Resolution *)MFHeap_Alloc(sizeof(Resolution) * (numModes + 1));

		for(int32 i = 0; i < numModes; i++)
		{
			modes[i].width = vidModes[i]->hdisplay;
			modes[i].height = vidModes[i]->vdisplay;
			modes[i].refresh = ((float)vidModes[i]->dotclock / (float)vidModes[i]->htotal) / (float)vidModes[i]->htotal;
		}

		modes[numModes].width = 0;
		modes[numModes].height = 0;
	}

	if(_modes != NULL)
		*_modes = modes;

	return true;
}
Пример #11
0
static bool get_video_mode(video_frame_info_t *video_info,
      Display *dpy, unsigned width, unsigned height,
      XF86VidModeModeInfo *mode, XF86VidModeModeInfo *desktop_mode)
{
   int i, num_modes            = 0;
   bool ret                    = false;
   float refresh_mod           = 0.0f;
   float minimum_fps_diff      = 0.0f;
   XF86VidModeModeInfo **modes = NULL;

   XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &num_modes, &modes);

   if (!num_modes)
   {
      XFree(modes);
      return false;
   }

   *desktop_mode = *modes[0];

   /* If we use black frame insertion, we fake a 60 Hz monitor
    * for 120 Hz one, etc, so try to match that. */
   refresh_mod = video_info->black_frame_insertion ? 0.5f : 1.0f;

   for (i = 0; i < num_modes; i++)
   {
      float refresh, diff;
      const XF86VidModeModeInfo *m = modes[i];

      if (!m)
         continue;

      if (m->hdisplay != width)
         continue;
      if (m->vdisplay != height)
         continue;

      refresh = refresh_mod * m->dotclock * 1000.0f / (m->htotal * m->vtotal);
      diff    = fabsf(refresh - video_info->refresh_rate);

      if (!ret || diff < minimum_fps_diff)
      {
         *mode = *m;
         minimum_fps_diff = diff;
      }
      ret = true;
   }

   XFree(modes);
   return ret;
}
Пример #12
0
Файл: vidmode.c Проект: aosm/X11
static void
GetModes(void)
{
    int i;
    char label[32];
    Arg args[1];
    static char menuName[16];
    static int menuN;

    XFree(vidtune->infos);
    XF86VidModeGetAllModeLines(XtDisplay(toplevel), vidtune->screen,
			       &vidtune->num_infos, &vidtune->infos);

    XmuSnprintf(menuName, sizeof(menuName), "menu%d", menuN);
    menuN = !menuN;
    if (menu)
	XtDestroyWidget(menu);
    menu = XtCreatePopupShell(menuName, simpleMenuWidgetClass, vtune, NULL, 0);
    XtVaSetValues(mode, XtNmenuName, menuName, NULL, 0);
    for (i = 0; i < vidtune->num_infos; i++) {
	Widget sme;

	if ((double)vidtune->infos[i]->htotal &&
	    (double)vidtune->infos[i]->vtotal)
	    XmuSnprintf(label, sizeof(label), "%dx%d @ %d Hz",
			vidtune->infos[i]->hdisplay,
			vidtune->infos[i]->vdisplay,
			(int)((double)vidtune->infos[i]->dotclock /
			(double)vidtune->infos[i]->htotal * 1000.0 /
			(double)vidtune->infos[i]->vtotal));
	else
	    XmuSnprintf(label, sizeof(label), "%dx%d",
			vidtune->infos[i]->hdisplay,
			vidtune->infos[i]->vdisplay);
	sme = XtCreateManagedWidget(label, smeBSBObjectClass, menu, NULL, 0);
	XtAddCallback(sme, XtNcallback, SelectCallback,
		      (XtPointer)vidtune->infos[i]);
    }

    if (modeline.htotal && modeline.vtotal)
	XmuSnprintf(label, sizeof(label), "%dx%d @ %d Hz",
		    modeline.hdisplay, modeline.vdisplay,
		    (int)((double)dot_clock / (double)modeline.htotal * 1000.0 /
		    (double)modeline.vtotal));
    else
	XmuSnprintf(label, sizeof(label), "%dx%d",
		    modeline.hdisplay, modeline.vdisplay);
    XtSetArg(args[0], XtNlabel, label);
    XtSetValues(mode, args, 1);
}
Пример #13
0
static void
ZoomInit(void)
{
   int                 ev_base, er_base;

   zoom_can = -1;

   if (!XF86VidModeQueryExtension(disp, &ev_base, &er_base))
      return;

   XF86VidModeGetAllModeLines(disp, Dpy.screen,
			      &std_vid_modes_num, &std_vid_modes);

   if (std_vid_modes_num > 1)
      zoom_can = 1;
}
Пример #14
0
int vidmode_init(void)
{
    unsigned int hz;
    int i;
    Display *display;

    vidmode_log = log_open("VidMode");

    display = x11ui_get_display_ptr();

    if (!XF86VidModeGetAllModeLines(display, screen, &vm_mode_count, &vm_modes)) {
        log_error(vidmode_log, "Error getting video mode information - disabling vidmode extension.");
        vm_available = 0;
        return 0;
    }

    for (i = 0; i < vm_mode_count; i++) {
        if (vm_modes[i]->hdisplay <= 800 && vm_modes[i]->hdisplay >= 320 && vm_modes[i]->vdisplay <= 600 && vm_modes[i]->vdisplay >= 200) {
            vm_bestmodes = (vm_bestvideomode_t *)lib_realloc(vm_bestmodes, (vm_index + 1) * sizeof(vm_bestvideomode_t));
            vm_bestmodes[vm_index].modeindex = i;

            if (vm_modes[i]->vtotal * vm_modes[i]->htotal) {
                hz = vm_modes[i]->dotclock * 1000 / (vm_modes[i]->vtotal * vm_modes[i]->htotal);
            } else {
                hz = 0;
            }

            vm_bestmodes[vm_index].name = lib_msprintf(" %ix%i-%iHz", vm_modes[i]->hdisplay, vm_modes[i]->vdisplay, hz);
            if (++vm_index > 29) {
                break;
            }
        }
    }

    if (vm_index == 0) {
        return 0;
    }

    vm_available = 1;
    return 0;
}
Пример #15
0
void fv_resetGeometry()
{
#ifdef HAVE_XF86_VMODE
    int oldMode, i;

    if (fullscreen) {
	XF86VidModeGetAllModeLines(Xdpy, Xscreen, &vmode_nb_modes, &vmode_modes);
	oldMode = 0;
	
	for (i=0; i < vmode_nb_modes; i++) {
	    if ((vmode_modes[i]->hdisplay == oldx) && (vmode_modes[i]->vdisplay==oldy)) {
		oldMode = i;
		break;
	    }
	}
	
	XF86VidModeSwitchToMode(Xdpy, Xscreen, vmode_modes[oldMode]);
	XF86VidModeSetViewPort(Xdpy, Xscreen, 0, 0);
	XFlush(Xdpy);
    }
#endif /* HAVE_XF86_VMODE */
}
Пример #16
0
/*
 * Changes the current display mode to match user's settings
 */
static GLboolean fghChangeDisplayMode( GLboolean haveToTest )
{
    GLboolean success = GL_FALSE;
#if TARGET_HOST_UNIX_X11

    /*
     * This highly depends on the XFree86 extensions,
     * not approved as X Consortium standards
     */
#   ifdef X_XF86VidModeGetAllModeLines

    /*
     * This is also used by applcations which check modes by calling
     * glutGameModeGet(GLUT_GAME_MODE_POSSIBLE), so allow the check:
     */
    if( haveToTest || fgDisplay.DisplayModeValid )
    {
        XF86VidModeModeInfo** displayModes;
        int i, displayModesCount;

        if( !XF86VidModeGetAllModeLines(
                 fgDisplay.Display,
                 fgDisplay.Screen,
                 &displayModesCount,
                 &displayModes ) )
        {
            fgWarning( "XF86VidModeGetAllModeLines failed" );
            return success;
        }


        /*
         * Check every of the modes looking for one that matches our demands,
         * ignoring the refresh rate if no exact match could be found.
         */
        i = fghCheckDisplayModes( GL_TRUE, displayModesCount, displayModes );
        if( i < 0 ) {
            i = fghCheckDisplayModes( GL_FALSE, displayModesCount, displayModes );
        }
        success = ( i < 0 ) ? GL_FALSE : GL_TRUE;

        if( !haveToTest && success ) {
            if( !XF86VidModeSwitchToMode(
                     fgDisplay.Display,
                     fgDisplay.Screen,
                     displayModes[ i ] ) )
                fgWarning( "XF86VidModeSwitchToMode failed" );
        }

        XFree( displayModes );
    }

#   else

    /*
     * XXX warning fghChangeDisplayMode: missing XFree86 video mode extensions,
     * XXX game mode will not change screen resolution when activated
     */
    success = GL_TRUE;

#   endif

#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE

    DEVMODE  devMode;
    char *fggmstr = NULL;

    success = GL_FALSE;

    EnumDisplaySettings( NULL, -1, &devMode ); 
    devMode.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;

    devMode.dmPelsWidth  = fgState.GameModeSize.X;
    devMode.dmPelsHeight = fgState.GameModeSize.Y;
    devMode.dmBitsPerPel = fgState.GameModeDepth;
    devMode.dmDisplayFrequency = fgState.GameModeRefresh;
    devMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;

    switch ( ChangeDisplaySettingsEx(NULL, &devMode, NULL, haveToTest ? CDS_TEST : CDS_FULLSCREEN , NULL) )
    {
    case DISP_CHANGE_SUCCESSFUL:
        success = GL_TRUE;

        /* update vars in case if windows switched to proper mode */
        EnumDisplaySettings( NULL, FREEGLUT_ENUM_CURRENT_SETTINGS, &devMode );
        fgState.GameModeSize.X  = devMode.dmPelsWidth;        
        fgState.GameModeSize.Y  = devMode.dmPelsHeight;
        fgState.GameModeDepth   = devMode.dmBitsPerPel;
        fgState.GameModeRefresh = devMode.dmDisplayFrequency;
		break;
    case DISP_CHANGE_RESTART:
        fggmstr = "The computer must be restarted for the graphics mode to work.";
        break;
    case DISP_CHANGE_BADFLAGS:
        fggmstr = "An invalid set of flags was passed in.";
        break;
    case DISP_CHANGE_BADPARAM:
        fggmstr = "An invalid parameter was passed in. This can include an invalid flag or combination of flags.";
        break;
    case DISP_CHANGE_FAILED:
        fggmstr = "The display driver failed the specified graphics mode.";
        break;
    case DISP_CHANGE_BADMODE:
        fggmstr = "The graphics mode is not supported.";
        break;
    default:
        fggmstr = "Unknown error in graphics mode???"; /* dunno if it is possible,MSDN does not mention any other error */
        break;
    }

    if ( !success )
        fgWarning(fggmstr); /* I'd rather get info whats going on in my program than wonder about */
                            /* magic happenings behind my back, its lib for devels at last ;) */
#endif

    return success;
}
Пример #17
0
/*
** GLW_SetMode
*/
int GLW_SetMode( const char *drivername, int mode, qboolean fullscreen ) {
#ifdef HAVE_GLES
	glConfig.vidWidth = 800;
	glConfig.vidHeight = 480;
//	glConfig.windowAspect = 800.0 / 480.0;

	long event_mask=X_MASK;
	dpy = XOpenDisplay(0);
	if(!dpy)
	{
		ri.Printf( PRINT_ALL, "couldn't open display\n");
		return qfalse;
	}
	
	scrnum = DefaultScreen(dpy);
	ri.Printf( PRINT_ALL, "using default screen %d\n", scrnum);
	ri.Printf( PRINT_ALL, "setting up EGL window\n");
 
	XSetWindowAttributes attr = { 0 };
	attr.event_mask = event_mask;
//	attr.colormap = colormap;
	attr.override_redirect = qtrue;
	win = XCreateWindow(dpy, RootWindow(dpy, scrnum),
		0, 0, glConfig.vidWidth, glConfig.vidHeight, 0, 
		CopyFromParent, InputOutput,
		CopyFromParent, CWEventMask, &attr);

	if(!win) {
		return qfalse;
	}

	Atom wmState = XInternAtom(dpy, "_NET_WM_STATE", False);
	Atom wmFullscreen = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
	XChangeProperty(dpy, win, wmState, XA_ATOM, 32, PropModeReplace, (unsigned char *)&wmFullscreen, 1);

	XMapRaised(dpy, win);

	g_EGLWindow = (NativeWindowType)win;
	#ifdef PANDORA
	g_EGLDisplay  =  eglGetDisplay((EGLNativeDisplayType)EGL_DEFAULT_DISPLAY);
	#else
	g_EGLDisplay  =  eglGetDisplay((EGLNativeDisplayType)dpy);
	#endif

	if(g_EGLDisplay == EGL_NO_DISPLAY) {
		ri.Printf( PRINT_ALL, "error getting EGL display\n");
		return qfalse;
	}

	if(!eglInitialize(g_EGLDisplay, NULL, NULL)) {
		ri.Printf( PRINT_ALL, "error initializing EGL");
		return 0;
	}

	const EGLint attribs[] = {
		EGL_RED_SIZE, 5,
		EGL_GREEN_SIZE, 6,
		EGL_BLUE_SIZE, 5,
		EGL_ALPHA_SIZE, 0,
		EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
		EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT,
		EGL_DEPTH_SIZE, 16,
		EGL_NONE, 0,
	};

	EGLint configs = 0;
	eglChooseConfig(g_EGLDisplay, attribs, &g_EGLConfig, 1, &configs);
	if(!configs) {
		static const EGLint eglAttrWinLowColor[] = {
			EGL_NONE
		};
		ri.Printf( PRINT_ALL, "falling back to lowest color config\n");
		eglChooseConfig(g_EGLDisplay, eglAttrWinLowColor, &g_EGLConfig, 1, &configs);
		if(!configs) {
			ri.Printf( PRINT_ALL, "no valid EGL configs found\n");
			return qfalse;
		}
	}
	
	#ifdef PANDORA
	g_EGLWindowSurface = eglCreateWindowSurface(g_EGLDisplay, g_EGLConfig,
		NULL, NULL);
	#else
	g_EGLWindowSurface = eglCreateWindowSurface(g_EGLDisplay, g_EGLConfig,
		g_EGLWindow, NULL);
	#endif
	if(g_EGLWindowSurface == EGL_NO_SURFACE) {
		ri.Printf( PRINT_ALL, "error creating window surface: 0x%X\n", (int)eglGetError());
		return qfalse;
	}

	EGLint ctxAttr[] = {
		EGL_CONTEXT_CLIENT_VERSION, 1,
		EGL_NONE
	};
	g_EGLContext = eglCreateContext(g_EGLDisplay, g_EGLConfig, EGL_NO_CONTEXT, ctxAttr);
	if(g_EGLContext == EGL_NO_CONTEXT) {
		ri.Printf( PRINT_ALL, "error creating context: 0x%X\n", (int)eglGetError());
		return qfalse;
	}
	
	eglMakeCurrent(g_EGLDisplay, g_EGLWindowSurface, g_EGLWindowSurface, g_EGLContext);
	{
	  EGLint width, height, color, depth, stencil;
	  eglQuerySurface(g_EGLDisplay, g_EGLWindowSurface, EGL_WIDTH, &width);
	  eglQuerySurface(g_EGLDisplay, g_EGLWindowSurface, EGL_HEIGHT, &height);
	  ri.Printf(PRINT_ALL, "Window size: %dx%d\n", width, height);
	  eglGetConfigAttrib(g_EGLDisplay, g_EGLConfig, EGL_BUFFER_SIZE, &color);
	  eglGetConfigAttrib(g_EGLDisplay, g_EGLConfig, EGL_DEPTH_SIZE, &depth);
	  eglGetConfigAttrib(g_EGLDisplay, g_EGLConfig, EGL_STENCIL_SIZE, &stencil);
/*	  glConfig.vidWidth = width;
	  glConfig.vidHeight = height;*/
	  glConfig.colorBits = color;
	  glConfig.depthBits = depth;
	  glConfig.stencilBits = stencil;
	}

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

#else
	int attrib[] = {
		GLX_RGBA,     // 0
		GLX_RED_SIZE, 4,  // 1, 2
		GLX_GREEN_SIZE, 4,  // 3, 4
		GLX_BLUE_SIZE, 4, // 5, 6
		GLX_DOUBLEBUFFER, // 7
		GLX_DEPTH_SIZE, 1,  // 8, 9
		GLX_STENCIL_SIZE, 1, // 10, 11
		None
	};
	// these match in the array
#define ATTR_RED_IDX 2
#define ATTR_GREEN_IDX 4
#define ATTR_BLUE_IDX 6
#define ATTR_DEPTH_IDX 9
#define ATTR_STENCIL_IDX 11
	Window root;
	XVisualInfo *visinfo;
	XSetWindowAttributes attr;
	unsigned long mask;
	int colorbits, depthbits, stencilbits;
	int tcolorbits, tdepthbits, tstencilbits;
	int dga_MajorVersion, dga_MinorVersion;
	int actualWidth, actualHeight;
	int i;
	const char*   glstring; // bk001130 - from cvs1.17 (mkv)

	ri.Printf( PRINT_ALL, "Initializing OpenGL display\n" );

	ri.Printf( PRINT_ALL, "...setting mode %d:", mode );

	if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) ) {
		ri.Printf( PRINT_ALL, " invalid mode\n" );
		return RSERR_INVALID_MODE;
	}
	ri.Printf( PRINT_ALL, " %d %d\n", glConfig.vidWidth, glConfig.vidHeight );

	if ( !( dpy = XOpenDisplay( NULL ) ) ) {
		fprintf( stderr, "Error couldn't open the X display\n" );
		return RSERR_INVALID_MODE;
	}

	scrnum = DefaultScreen( dpy );
	root = RootWindow( dpy, scrnum );

	actualWidth = glConfig.vidWidth;
	actualHeight = glConfig.vidHeight;

	// Get video mode list
	if ( !XF86VidModeQueryVersion( dpy, &vidmode_MajorVersion, &vidmode_MinorVersion ) ) {
		vidmode_ext = qfalse;
	} else
	{
		ri.Printf( PRINT_ALL, "Using XFree86-VidModeExtension Version %d.%d\n",
				   vidmode_MajorVersion, vidmode_MinorVersion );
		vidmode_ext = qtrue;
	}

	// Check for DGA
	dga_MajorVersion = 0, dga_MinorVersion = 0;
	if ( in_dgamouse->value ) {
		if ( !XF86DGAQueryVersion( dpy, &dga_MajorVersion, &dga_MinorVersion ) ) {
			// unable to query, probalby not supported
			ri.Printf( PRINT_ALL, "Failed to detect XF86DGA Mouse\n" );
			ri.Cvar_Set( "in_dgamouse", "0" );
		} else
		{
			ri.Printf( PRINT_ALL, "XF86DGA Mouse (Version %d.%d) initialized\n",
					   dga_MajorVersion, dga_MinorVersion );
		}
	}

	if ( vidmode_ext ) {
		int best_fit, best_dist, dist, x, y;

		XF86VidModeGetAllModeLines( dpy, scrnum, &num_vidmodes, &vidmodes );

		// Are we going fullscreen?  If so, let's change video mode
		if ( fullscreen ) {
			best_dist = 9999999;
			best_fit = -1;

			for ( i = 0; i < num_vidmodes; i++ )
			{
				if ( glConfig.vidWidth > vidmodes[i]->hdisplay ||
					 glConfig.vidHeight > vidmodes[i]->vdisplay ) {
					continue;
				}

				x = glConfig.vidWidth - vidmodes[i]->hdisplay;
				y = glConfig.vidHeight - vidmodes[i]->vdisplay;
				dist = ( x * x ) + ( y * y );
				if ( dist < best_dist ) {
					best_dist = dist;
					best_fit = i;
				}
			}

			if ( best_fit != -1 ) {
				actualWidth = vidmodes[best_fit]->hdisplay;
				actualHeight = vidmodes[best_fit]->vdisplay;

				// change to the mode
				XF86VidModeSwitchToMode( dpy, scrnum, vidmodes[best_fit] );
				vidmode_active = qtrue;

				// Move the viewport to top left
				XF86VidModeSetViewPort( dpy, scrnum, 0, 0 );

				ri.Printf( PRINT_ALL, "XFree86-VidModeExtension Activated at %dx%d\n",
						   actualWidth, actualHeight );

			} else
			{
				fullscreen = 0;
				ri.Printf( PRINT_ALL, "XFree86-VidModeExtension: No acceptable modes found\n" );
			}
		} else
		{
			ri.Printf( PRINT_ALL, "XFree86-VidModeExtension:  Ignored on non-fullscreen/Voodoo\n" );
		}
	}


	if ( !r_colorbits->value ) {
		colorbits = 24;
	} else {
		colorbits = r_colorbits->value;
	}

	if ( !Q_stricmp( r_glDriver->string, _3DFX_DRIVER_NAME ) ) {
		colorbits = 16;
	}

	if ( !r_depthbits->value ) {
		depthbits = 24;
	} else {
		depthbits = r_depthbits->value;
	}
	stencilbits = r_stencilbits->value;

	for ( i = 0; i < 16; i++ )
	{
		// 0 - default
		// 1 - minus colorbits
		// 2 - minus depthbits
		// 3 - minus stencil
		if ( ( i % 4 ) == 0 && i ) {
			// one pass, reduce
			switch ( i / 4 )
			{
			case 2:
				if ( colorbits == 24 ) {
					colorbits = 16;
				}
				break;
			case 1:
				if ( depthbits == 24 ) {
					depthbits = 16;
				} else if ( depthbits == 16 ) {
					depthbits = 8;
				}
			case 3:
				if ( stencilbits == 24 ) {
					stencilbits = 16;
				} else if ( stencilbits == 16 ) {
					stencilbits = 8;
				}
			}
		}

		tcolorbits = colorbits;
		tdepthbits = depthbits;
		tstencilbits = stencilbits;

		if ( ( i % 4 ) == 3 ) { // reduce colorbits
			if ( tcolorbits == 24 ) {
				tcolorbits = 16;
			}
		}

		if ( ( i % 4 ) == 2 ) { // reduce depthbits
			if ( tdepthbits == 24 ) {
				tdepthbits = 16;
			} else if ( tdepthbits == 16 ) {
				tdepthbits = 8;
			}
		}

		if ( ( i % 4 ) == 1 ) { // reduce stencilbits
			if ( tstencilbits == 24 ) {
				tstencilbits = 16;
			} else if ( tstencilbits == 16 ) {
				tstencilbits = 8;
			} else {
				tstencilbits = 0;
			}
		}

		if ( tcolorbits == 24 ) {
			attrib[ATTR_RED_IDX] = 8;
			attrib[ATTR_GREEN_IDX] = 8;
			attrib[ATTR_BLUE_IDX] = 8;
		} else
		{
			// must be 16 bit
			attrib[ATTR_RED_IDX] = 4;
			attrib[ATTR_GREEN_IDX] = 4;
			attrib[ATTR_BLUE_IDX] = 4;
		}

		attrib[ATTR_DEPTH_IDX] = tdepthbits; // default to 24 depth
		attrib[ATTR_STENCIL_IDX] = tstencilbits;

		visinfo = qglXChooseVisual( dpy, scrnum, attrib );
		if ( !visinfo ) {
			continue;
		}

		ri.Printf( PRINT_ALL, "Using %d/%d/%d Color bits, %d depth, %d stencil display.\n",
				   attrib[ATTR_RED_IDX], attrib[ATTR_GREEN_IDX], attrib[ATTR_BLUE_IDX],
				   attrib[ATTR_DEPTH_IDX], attrib[ATTR_STENCIL_IDX] );

		glConfig.colorBits = tcolorbits;
		glConfig.depthBits = tdepthbits;
		glConfig.stencilBits = tstencilbits;
		break;
	}

	if ( !visinfo ) {
		ri.Printf( PRINT_ALL, "Couldn't get a visual\n" );
		return RSERR_INVALID_MODE;
	}

	/* window attributes */
	attr.background_pixel = BlackPixel( dpy, scrnum );
	attr.border_pixel = 0;
	attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone );
	attr.event_mask = X_MASK;
	if ( vidmode_active ) {
		mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore |
			   CWEventMask | CWOverrideRedirect;
		attr.override_redirect = True;
		attr.backing_store = NotUseful;
		attr.save_under = False;
	} else {
		mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
	}

	win = XCreateWindow( dpy, root, 0, 0,
						 actualWidth, actualHeight,
						 0, visinfo->depth, InputOutput,
						 visinfo->visual, mask, &attr );

	XStoreName( dpy, win, WINDOW_CLASS_NAME );

	XMapWindow( dpy, win );

	if ( vidmode_active ) {
		XMoveWindow( dpy, win, 0, 0 );
	}

	XFlush( dpy );
	XSync( dpy,False ); // bk001130 - from cvs1.17 (mkv)
	ctx = qglXCreateContext( dpy, visinfo, NULL, True );
	XSync( dpy,False ); // bk001130 - from cvs1.17 (mkv)

	qglXMakeCurrent( dpy, win, ctx );

	// bk001130 - from cvs1.17 (mkv)
	glstring = qglGetString( GL_RENDERER );
	ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glstring );

	// bk010122 - new software token (Indirect)
	if ( !Q_stricmp( glstring, "Mesa X11" )
		 || !Q_stricmp( glstring, "Mesa GLX Indirect" ) ) {
		if ( !r_allowSoftwareGL->integer ) {
			ri.Printf( PRINT_ALL, "\n\n***********************************************************\n" );
			ri.Printf( PRINT_ALL, " You are using software Mesa (no hardware acceleration)!   \n" );
			ri.Printf( PRINT_ALL, " Driver DLL used: %s\n", drivername );
			ri.Printf( PRINT_ALL, " If this is intentional, add\n" );
			ri.Printf( PRINT_ALL, "       \"+set r_allowSoftwareGL 1\"\n" );
			ri.Printf( PRINT_ALL, " to the command line when starting the game.\n" );
			ri.Printf( PRINT_ALL, "***********************************************************\n" );
			GLimp_Shutdown();
			return RSERR_INVALID_MODE;
		} else
		{
			ri.Printf( PRINT_ALL, "...using software Mesa (r_allowSoftwareGL==1).\n" );
		}
	}
#endif	//HAVE_GLES
	return RSERR_OK;
}
Пример #18
0
GLWindow::GLWindow(const char * title, int width, int height, int bits, bool fullscreen, WNDPROC wndproc)
{
#ifdef _WIN32
	GLuint PixelFormat;			            // Holds The Results After Searching For A Match
	WNDCLASS wc;						            // Windows Class Structure
	DWORD dwExStyle;				            // Window Extended Style
	DWORD dwStyle;				              // Window Style
	RECT WindowRect;				            // Grabs Rectangle Upper Left / Lower Right Values
	WindowRect.left = (long) 0;			    // Set Left Value To 0
	WindowRect.right =(long) width;		  // Set Right Value To Requested Width
	WindowRect.top = (long) 0;				  // Set Top Value To 0
	WindowRect.bottom = (long) height;  // Set Bottom Value To Requested Height
  bool result = true;
  mInitialized = false;

  if(result) {
	  mhInstance = GetModuleHandle(NULL);				
	  wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;	
	  wc.lpfnWndProc = (WNDPROC) wndproc;
	  wc.cbClsExtra = 0;									
	  wc.cbWndExtra = 0;									
    wc.hInstance = mhInstance;					
	  wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);		
	  wc.hCursor = LoadCursor(NULL, IDC_ARROW);	
	  wc.hbrBackground = NULL;							
	  wc.lpszMenuName = NULL;							
	  wc.lpszClassName = "OpenGL";
  }
  
  if(result) {
	  if(!RegisterClass(&wc)) {
		  result = false;
	  }
  }

  if(result) {
	  DEVMODE dmScreenSettings;								
	  memset(&dmScreenSettings,0,sizeof(dmScreenSettings));
	  dmScreenSettings.dmSize=sizeof(dmScreenSettings);
	  dmScreenSettings.dmPelsWidth	= width;
	  dmScreenSettings.dmPelsHeight	= height;
	  dmScreenSettings.dmBitsPerPel	= bits;
	  dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;

    if(fullscreen) {
		  ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
		  dwExStyle = WS_EX_APPWINDOW;
		  dwStyle = WS_POPUP;
	  }	else {
		  dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
		  dwStyle = WS_OVERLAPPEDWINDOW;					
	  }

    AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);	
  }

  if(result) {
    dwStyle |=	WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
    mhWnd = CreateWindowEx(dwExStyle, "OpenGL", title, dwStyle, 0, 0, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top,	NULL,	NULL, mhInstance, NULL);

    if(!mhWnd) {
		  free();
		  result = false;		
	  }
  }
	
  if(result) {
    mhDC = GetDC(mhWnd);
	  if(!mhDC)	{
		  free();
		  result = false;	
	  }
  }

  static PIXELFORMATDESCRIPTOR pfd =	
	{
		sizeof(PIXELFORMATDESCRIPTOR),		
		1,										
		PFD_DRAW_TO_WINDOW |	
		PFD_SUPPORT_OPENGL |	
		PFD_DOUBLEBUFFER,			
		PFD_TYPE_RGBA,				
		bits,									
		0, 0, 0, 0, 0, 0,			
		0,										
		0,										
		0,										
		0, 0, 0, 0,						
		16,										
		0,										
		0,										
		PFD_MAIN_PLANE,				
		0,										
		0, 0, 0								
	};

  if(result) {
    PixelFormat = ChoosePixelFormat(mhDC, &pfd);
	  if(!PixelFormat) {
		  free();
		  result = false;	
	  }
  }

  if(result) {
	  if(!SetPixelFormat(mhDC, PixelFormat, &pfd))	{
		  free();
		  result = false;	
	  }
  }

  if(result) {
    mhRC = wglCreateContext(mhDC);
	  if(!mhRC) {
		  free();
		  result = false;	
	  }
  }

  if(result) {
	  if(!wglMakeCurrent(mhDC, mhRC))	{
		  free();
		  result = false;							
	  }
  }

  if(result) {
    ShowCursor(FALSE);
	  ShowWindow(mhWnd, SW_SHOW);				
	  SetForegroundWindow(mhWnd);			
	  SetFocus(mhWnd);									
  }

  if(result) {
	  if(!initOpenGL()) {
		  free();
		  result = false;	
	  }
  }

  mInitialized = result;
#else            
  XVisualInfo *vi;
  Colormap cmap;  
  int i, dpyWidth, dpyHeight;
  int glxMajor, glxMinor, vmMajor, vmMinor;
  XF86VidModeModeInfo **modes;             
  int modeNum, bestMode;                   
  Atom wmDelete;                           
  Window winDummy;                         
  unsigned int borderDummy;                

  mFullscreen = fullscreen;

  /* set best mode to current */
  bestMode = 0;                 
  /* get a connection */        
  mDisplay = XOpenDisplay(0);    
  mScreen = DefaultScreen(mDisplay);
  XF86VidModeQueryVersion(mDisplay, &vmMajor, &vmMinor);
  XF86VidModeGetAllModeLines(mDisplay, mScreen, &modeNum, &modes);       
  /* save desktop-resolution before switching modes */                 
  mDeskMode = *modes[0];
  /* look for mode with requested resolution */                        
  for (i = 0; i < modeNum; i++)                                        
  {                                                                    
      if ((modes[i]->hdisplay == width) && (modes[i]->vdisplay == height))
          bestMode = i;                                                   
  }                                                                       
  /* get an appropriate visual */                                         
  vi = glXChooseVisual(mDisplay, mScreen, attrListDbl);                     
  if (vi == NULL)                                                         
  {                                                                       
      vi = glXChooseVisual(mDisplay, mScreen, attrListSgl);                 
      mDoubleBuffered = False;                                             
  }                                                                                   
  else                                                                                
  {                                                                                   
      mDoubleBuffered = True;                                                                                        
  }                                                                                   
  glXQueryVersion(mDisplay, &glxMajor, &glxMinor);                                     
  Debug::Log("GLX-Version %d.%d\n", glxMajor, glxMinor); 
  /* create a GLX context */                                                          
  mCtx = glXCreateContext(mDisplay, vi, 0, GL_TRUE);                                
  /* create a color map */                                                            
  cmap = XCreateColormap(mDisplay, RootWindow(mDisplay, vi->screen),                    
      vi->visual, AllocNone);                                                         
  mWinAttr.colormap = cmap;                                                            
  mWinAttr.border_pixel = 0;                                                           

  if(fullscreen)
  {              
      /* switch to fullscreen */
      XF86VidModeSwitchToMode(mDisplay, mScreen, modes[bestMode]);
      XF86VidModeSetViewPort(mDisplay, mScreen, 0, 0);            
      dpyWidth = modes[bestMode]->hdisplay;                     
      dpyHeight = modes[bestMode]->vdisplay;                          
      XFree(modes);                                             

      /* set window attributes */
      mWinAttr.override_redirect = True;
      mWinAttr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
          StructureNotifyMask;                                            
      mWindow = XCreateWindow(mDisplay, RootWindow(mDisplay, vi->screen),    
          0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual,
          CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect,   
          &mWinAttr);                                                       
      XWarpPointer(mDisplay, None, mWindow, 0, 0, 0, 0, 0, 0);               
              XMapRaised(mDisplay, mWindow);                                 
      XGrabKeyboard(mDisplay, mWindow, True, GrabModeAsync,                  
          GrabModeAsync, CurrentTime);                                     
      XGrabPointer(mDisplay, mWindow, True, ButtonPressMask,                 
          GrabModeAsync, GrabModeAsync, mWindow, None, CurrentTime);        
  }                                                                        
  else                                                                     
  {                                                                        
      /* create a window in window mode*/                                  
      mWinAttr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | 
          StructureNotifyMask;                                             
      mWindow = XCreateWindow(mDisplay, RootWindow(mDisplay, vi->screen),        
          0, 0, width, height, 0, vi->depth, InputOutput, vi->visual,      
          CWBorderPixel | CWColormap | CWEventMask, &mWinAttr);             
      /* only set window title and handle wm_delete_events if in windowed mode */
      wmDelete = XInternAtom(mDisplay, "WM_DELETE_WINDOW", True);                 
      XSetWMProtocols(mDisplay, mWindow, &wmDelete, 1);                            
      XSetStandardProperties(mDisplay, mWindow, title,                             
          title, None, NULL, 0, NULL);                                           
      XMapRaised(mDisplay, mWindow);                                               
  }                                                                              
  /* connect the glx-context to the window */                                    
  glXMakeCurrent(mDisplay, mWindow, mCtx);                                                                                
  initOpenGL();

  mInitialized = true;    
#endif
}
Пример #19
0
static _GLFWvidsize* getResolutions(int* found)
{
    int i, j;
    _GLFWvidsize* result = NULL;

    *found = 0;

    // Build array of available resolutions

    if (_glfwLibrary.X11.RandR.available)
    {
#if defined(_GLFW_HAS_XRANDR)
        XRRScreenConfiguration* sc;
        XRRScreenSize* sizes;

        sc = XRRGetScreenInfo(_glfwLibrary.X11.display, _glfwLibrary.X11.root);
        sizes = XRRConfigSizes(sc, found);

        result = (_GLFWvidsize*) malloc(sizeof(_GLFWvidsize) * *found);

        for (i = 0;  i < *found;  i++)
        {
            result[i].width  = sizes[i].width;
            result[i].height = sizes[i].height;
        }

        XRRFreeScreenConfigInfo(sc);
#endif /*_GLFW_HAS_XRANDR*/
    }
    else if (_glfwLibrary.X11.VidMode.available)
    {
#if defined(_GLFW_HAS_XF86VIDMODE)
        XF86VidModeModeInfo** modes;
        int modeCount;

        XF86VidModeGetAllModeLines(_glfwLibrary.X11.display,
                                   _glfwLibrary.X11.screen,
                                   &modeCount, &modes);

        result = (_GLFWvidsize*) malloc(sizeof(_GLFWvidsize) * modeCount);

        for (i = 0;  i < modeCount;  i++)
        {
            _GLFWvidsize size;
            size.width  = modes[i]->hdisplay;
            size.height = modes[i]->vdisplay;

            for (j = 0;  j < *found;  j++)
            {
                if (memcmp(result + j, &size, sizeof(_GLFWvidsize)) == 0)
                    break;
            }

            if (j < *found)
            {
                // This size is a duplicate, so skip it
                continue;
            }

            result[*found] = size;
            (*found)++;
        }

        XFree(modes);
#endif /*_GLFW_HAS_XF86VIDMODE*/
    }

    if (result == NULL)
    {
        *found = 1;
        result = (_GLFWvidsize*) malloc(sizeof(_GLFWvidsize));

        result[0].width = DisplayWidth(_glfwLibrary.X11.display,
                                       _glfwLibrary.X11.screen);
        result[0].height = DisplayHeight(_glfwLibrary.X11.display,
                                         _glfwLibrary.X11.screen);
    }

    return result;
}
Пример #20
0
void _glfwSetVideoModeMODE(int mode, int rate)
{
    if (_glfwLibrary.X11.RandR.available)
    {
#if defined(_GLFW_HAS_XRANDR)
        XRRScreenConfiguration* sc;
        Window root;

        root = _glfwLibrary.X11.root;
        sc   = XRRGetScreenInfo(_glfwLibrary.X11.display, root);

        // Remember old size and flag that we have changed the mode
        if (!_glfwLibrary.X11.FS.modeChanged)
        {
            _glfwLibrary.X11.FS.oldSizeID = XRRConfigCurrentConfiguration(sc, &_glfwLibrary.X11.FS.oldRotation);
            _glfwLibrary.X11.FS.oldWidth  = DisplayWidth(_glfwLibrary.X11.display,
                                                         _glfwLibrary.X11.screen);
            _glfwLibrary.X11.FS.oldHeight = DisplayHeight(_glfwLibrary.X11.display,
                                                          _glfwLibrary.X11.screen);

            _glfwLibrary.X11.FS.modeChanged = GL_TRUE;
        }

        if (rate > 0)
        {
            // Set desired configuration
            XRRSetScreenConfigAndRate(_glfwLibrary.X11.display,
                                      sc,
                                      root,
                                      mode,
                                      RR_Rotate_0,
                                      (short) rate,
                                      CurrentTime);
        }
        else
        {
            // Set desired configuration
            XRRSetScreenConfig(_glfwLibrary.X11.display,
                               sc,
                               root,
                               mode,
                               RR_Rotate_0,
                               CurrentTime);
        }

        XRRFreeScreenConfigInfo(sc);
#endif /*_GLFW_HAS_XRANDR*/
    }
    else if (_glfwLibrary.X11.VidMode.available)
    {
#if defined(_GLFW_HAS_XF86VIDMODE)
        XF86VidModeModeInfo **modelist;
        int modecount;

        // Get a list of all available display modes
        XF86VidModeGetAllModeLines(_glfwLibrary.X11.display,
                                   _glfwLibrary.X11.screen,
                                   &modecount, &modelist);

        // Unlock mode switch if necessary
        if (_glfwLibrary.X11.FS.modeChanged)
        {
            XF86VidModeLockModeSwitch(_glfwLibrary.X11.display,
                                      _glfwLibrary.X11.screen,
                                      0);
        }

        // Change the video mode to the desired mode
        XF86VidModeSwitchToMode(_glfwLibrary.X11.display,
                                _glfwLibrary.X11.screen,
                                modelist[mode]);

        // Set viewport to upper left corner (where our window will be)
        XF86VidModeSetViewPort(_glfwLibrary.X11.display,
                               _glfwLibrary.X11.screen,
                               0, 0);

        // Lock mode switch
        XF86VidModeLockModeSwitch(_glfwLibrary.X11.display,
                                  _glfwLibrary.X11.screen,
                                  1);

        // Remember old mode and flag that we have changed the mode
        if (!_glfwLibrary.X11.FS.modeChanged)
        {
            _glfwLibrary.X11.FS.oldMode = *modelist[0];
            _glfwLibrary.X11.FS.modeChanged = GL_TRUE;
        }

        XFree(modelist);
#endif /*_GLFW_HAS_XF86VIDMODE*/
    }
}
Пример #21
0
int _glfwGetClosestVideoMode(int* width, int* height, int* rate)
{
    int i, match, bestmatch;

    if (_glfwLibrary.X11.RandR.available)
    {
#if defined(_GLFW_HAS_XRANDR)
        int sizecount, bestsize;
        int ratecount, bestrate;
        short* ratelist;
        XRRScreenConfiguration* sc;
        XRRScreenSize* sizelist;

        sc = XRRGetScreenInfo(_glfwLibrary.X11.display, _glfwLibrary.X11.root);

        sizelist = XRRConfigSizes(sc, &sizecount);

        // Find the best matching mode
        bestsize  = -1;
        bestmatch = INT_MAX;
        for (i = 0;  i < sizecount;  i++)
        {
            match = (*width - sizelist[i].width) *
                    (*width - sizelist[i].width) +
                    (*height - sizelist[i].height) *
                    (*height - sizelist[i].height);
            if (match < bestmatch)
            {
                bestmatch = match;
                bestsize  = i;
            }
        }

        if (bestsize != -1)
        {
            // Report width & height of best matching mode
            *width = sizelist[bestsize].width;
            *height = sizelist[bestsize].height;

            if (*rate > 0)
            {
                ratelist = XRRConfigRates(sc, bestsize, &ratecount);

                bestrate = -1;
                bestmatch = INT_MAX;
                for (i = 0;  i < ratecount;  i++)
                {
                    match = abs(ratelist[i] - *rate);
                    if (match < bestmatch)
                    {
                        bestmatch = match;
                        bestrate = ratelist[i];
                    }
                }

                if (bestrate != -1)
                    *rate = bestrate;
            }
        }

        XRRFreeScreenConfigInfo(sc);

        if (bestsize != -1)
            return bestsize;
#endif /*_GLFW_HAS_XRANDR*/
    }
    else if (_glfwLibrary.X11.VidMode.available)
    {
#if defined(_GLFW_HAS_XF86VIDMODE)
        XF86VidModeModeInfo** modelist;
        int bestmode, modecount;

        // Get a list of all available display modes
        XF86VidModeGetAllModeLines(_glfwLibrary.X11.display,
                                   _glfwLibrary.X11.screen,
                                   &modecount, &modelist);

        // Find the best matching mode
        bestmode  = -1;
        bestmatch = INT_MAX;
        for (i = 0;  i < modecount;  i++)
        {
            match = (*width - modelist[i]->hdisplay) *
                    (*width - modelist[i]->hdisplay) +
                    (*height - modelist[i]->vdisplay) *
                    (*height - modelist[i]->vdisplay);
            if (match < bestmatch)
            {
                bestmatch = match;
                bestmode  = i;
            }
        }

        if (bestmode != -1)
        {
            // Report width & height of best matching mode
            *width = modelist[bestmode]->hdisplay;
            *height = modelist[bestmode]->vdisplay;
        }

        XFree(modelist);

        if (bestmode != -1)
            return bestmode;
#endif /*_GLFW_HAS_XF86VIDMODE*/
    }

    // Default: Simply use the screen resolution
    *width = DisplayWidth(_glfwLibrary.X11.display, _glfwLibrary.X11.screen);
    *height = DisplayHeight(_glfwLibrary.X11.display, _glfwLibrary.X11.screen);

    return 0;
}
Пример #22
0
Error ContextGL_X11::initialize() {

	
	GLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = NULL;
	
//	const char *extensions = glXQueryExtensionsString(x11_display, DefaultScreen(x11_display));
	
	glXCreateContextAttribsARB = (GLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
	
	ERR_FAIL_COND_V( !glXCreateContextAttribsARB, ERR_UNCONFIGURED );


	static int visual_attribs[] = {
	    GLX_RENDER_TYPE, GLX_RGBA_BIT,
	    GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
	    GLX_DOUBLEBUFFER, true,
	    GLX_RED_SIZE, 1,
	    GLX_GREEN_SIZE, 1,
	    GLX_BLUE_SIZE, 1,
	    GLX_DEPTH_SIZE, 24,
	    None 
	};

	int fbcount;
	GLXFBConfig *fbc = glXChooseFBConfig(x11_display, DefaultScreen(x11_display), visual_attribs, &fbcount);
	ERR_FAIL_COND_V(!fbc,ERR_UNCONFIGURED);
	
	XVisualInfo *vi = glXGetVisualFromFBConfig(x11_display, fbc[0]);

	XSetWindowAttributes swa;

	swa.colormap = XCreateColormap(x11_display, RootWindow(x11_display, vi->screen), vi->visual, AllocNone);
	swa.border_pixel = 0;
	swa.event_mask = StructureNotifyMask;

	/*
	char* windowid = getenv("GODOT_WINDOWID");
	if (windowid) {

		//freopen("/home/punto/stdout", "w", stdout);
		//reopen("/home/punto/stderr", "w", stderr);
		x11_window = atol(windowid);
	} else {
	*/

    x11MotivHints.flags         = 2;
    x11MotivHints.decorations   = 0;
    xiaNewProperty              = XInternAtom( x11_display,"_MOTIF_WM_HINTS", True );
    vidModeBest                 = 0;
    vidModeCount                = 0;
    windowWidth                 = 1024;
    windowHeight                = 768;
    dpyWidth                    = 0;
    dpyHeight                   = 0;
    screenBackup                = vi->screen;

    XF86VidModeGetAllModeLines( x11_display, vi->screen, &vidModeCount, &vidModes );

    printf("Debug: vidModeCount=%d\n", vidModeCount );

    desktopMode = *vidModes[ 0 ];

    for ( int i = 0; i < vidModeCount; i++ ){

        if (( vidModes[i]->hdisplay == windowWidth) && ( vidModes[i]->vdisplay == windowHeight ))
                    vidModeBest = i;

    }

    printf("vidModeBest=%d\n",vidModeBest);

    glXQueryVersion(    x11_display, &glxMajor, &glxMinor                 );
    printf(             "Debug: GLX-Version %d.%d\n", glxMajor, glxMinor  );

    context                 = glXCreateContext( x11_display, vi, 0, GL_TRUE                                                 );
    cmap                    = XCreateColormap(  x11_display, RootWindow( x11_display, vi->screen ), vi->visual, AllocNone   );
    winAttr.colormap        = cmap;
    winAttr.border_pixel    = 0;

    XChangeProperty(            x11_display, RootWindow( x11_display, vi->screen ), xiaNewProperty, xiaNewProperty, 32, PropModeReplace, ( unsigned char * ) &x11MotivHints, 5        );
    XF86VidModeSwitchToMode(    x11_display, vi->screen, vidModes[ vidModeBest ]                                                                                                        );
    XF86VidModeSetViewPort(     x11_display, vi->screen, 0, 0                                                                                                                         );
    XMoveResizeWindow(          x11_display, RootWindow( x11_display, vi->screen ), 0, 0, OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height   );
    XMapRaised(                 x11_display, RootWindow( x11_display, vi->screen )                                                                                                    );

    dpyWidth    = vidModes[vidModeBest]->hdisplay;
    dpyHeight   = vidModes[vidModeBest]->vdisplay;

    XFree(vidModes);

    winAttr.override_redirect   = True;
    winAttr.event_mask          = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask;

    x11_window = XCreateWindow( x11_display,
                                RootWindow( x11_display, vi->screen ),
                                0, 0,
                                dpyWidth, dpyHeight,
                                0,
                                vi->depth,
                                InputOutput,
                                vi->visual,
                                CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &winAttr );
    XWarpPointer(               x11_display,
                                None,
                                x11_window,
                                0, 0, 0, 0, 0, 0                                                        );
    XMapRaised(                 x11_display, x11_window                                                 );
    XGrabKeyboard(              x11_display, x11_window,
                                True,
                                GrabModeAsync, GrabModeAsync,
                                CurrentTime                                                             );
    XGrabPointer(               x11_display, x11_window,
                                True, ButtonPressMask,
                                GrabModeAsync, GrabModeAsync,
                                x11_window,
                                None,
                                CurrentTime                                                             );

        //x11_window = XCreateWindow(x11_display, RootWindow(x11_display, vi->screen), 0, 0, OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa);
		ERR_FAIL_COND_V(!x11_window,ERR_UNCONFIGURED);
		XMapWindow(x11_display, x11_window);
		while(true) {
			// wait for mapnotify (window created)
			XEvent e;
			XNextEvent(x11_display, &e);
			if (e.type == MapNotify)
				break;
		}
		//};

	if (!OS::get_singleton()->get_video_mode().resizable) {
		XSizeHints *xsh;
		xsh = XAllocSizeHints();
		xsh->flags = PMinSize | PMaxSize;
		xsh->min_width = OS::get_singleton()->get_video_mode().width;
		xsh->max_width = OS::get_singleton()->get_video_mode().width;
		xsh->min_height = OS::get_singleton()->get_video_mode().height;
		xsh->max_height = OS::get_singleton()->get_video_mode().height;
		XSetWMNormalHints(x11_display, x11_window, xsh);
	}


	if (!opengl_3_context) {
		//oldstyle context:
		p->glx_context = glXCreateContext(x11_display, vi, 0, GL_TRUE);
	} else {
		static int context_attribs[] = {
			GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
			GLX_CONTEXT_MINOR_VERSION_ARB, 0,
			None
		};
	
		p->glx_context = glXCreateContextAttribsARB(x11_display, fbc[0], NULL, true, context_attribs);
		ERR_FAIL_COND_V(!p->glx_context,ERR_UNCONFIGURED);
	}

	glXMakeCurrent(x11_display, x11_window, p->glx_context);

	/*
	glWrapperInit(wrapper_get_proc_address);
	glFlush();
	
	glXSwapBuffers(x11_display,x11_window);
*/
	//glXMakeCurrent(x11_display, None, NULL);

	return OK;
}
Пример #23
0
bool fxwt::init_graphics(GraphicsInitParameters *gparams) {
	Display *dpy;
	Window win;
	info("Initializing GLX");

	if(!(dpy = XOpenDisplay(0))) {
		error("Could not connect to the X server");
		return false;
	}

	int screen = DefaultScreen(dpy);
	Window root_win = RootWindow(dpy, screen);

	info("Trying to set video mode %dx%dx%d, d:%d s:%d %s", gparams->x, gparams->y, gparams->bpp, gparams->depth_bits, gparams->stencil_bits, gparams->fullscreen ? "fullscreen" : "windowed");
	
	// determine color bits
	int color_bits = 1;
	if(!(gparams->dont_care_flags & DONT_CARE_BPP)) {
		switch(gparams->bpp) {
		case 32:
		case 24:
			color_bits = 8;
			break;

		case 16:
		case 15:
			color_bits = 5;
			break;

		case 12:
			color_bits = 4;
			break;

		default:
			error("%s: Tried to set unsupported pixel format: %d bpp", __func__, gparams->bpp);
		}
	}

	// determine stencil bits
	int stencil_bits = gparams->stencil_bits;
	if(gparams->dont_care_flags & DONT_CARE_STENCIL) {
		stencil_bits = 1;
	}

	// determine zbuffer bits
	int zbits = gparams->depth_bits == 32 ? 24 : gparams->depth_bits;
	if(gparams->dont_care_flags & DONT_CARE_BPP) {
		zbits = 1;
	}
	
	int glx_attrib[] = {
		GLX_RGBA, GLX_DOUBLEBUFFER,
		GLX_RED_SIZE, color_bits,
		GLX_GREEN_SIZE, color_bits,
		GLX_BLUE_SIZE, color_bits,
		GLX_DEPTH_SIZE, zbits,
		GLX_STENCIL_SIZE, stencil_bits,
		None
	};

	XVisualInfo *vis_info;
	if(!(vis_info = glXChooseVisual(dpy, screen, glx_attrib))) {
		error("%s: Could not set requested video mode", __func__);
		XCloseDisplay(dpy);
		return false;
	}

	// check the video mode we got
	int arbits, agbits, abbits, azbits, astencilbits;
	glXGetConfig(dpy, vis_info, GLX_RED_SIZE, &arbits);
	glXGetConfig(dpy, vis_info, GLX_GREEN_SIZE, &agbits);
	glXGetConfig(dpy, vis_info, GLX_BLUE_SIZE, &abbits);
	glXGetConfig(dpy, vis_info, GLX_DEPTH_SIZE, &azbits);
	glXGetConfig(dpy, vis_info, GLX_STENCIL_SIZE, &astencilbits);

	info("Initialized video mode:");
	info("    bpp: %d (%d%d%d)", arbits + agbits + abbits, arbits, agbits, abbits);
	info("zbuffer: %d", azbits);
	info("stencil: %d", astencilbits);

	/* if the dont_care_flags does not contain DONT_CARE_BPP and our color bits
	 * does not match, we should return failure, however we test against
	 * the difference allowing a +/-1 difference in order to allow for 16bpp
	 * formats of either 565 or 555 and consider them equal.
	 */
	if(!(gparams->dont_care_flags & DONT_CARE_BPP) && abs(arbits - color_bits) > 1 && abs(agbits - color_bits) > 1 && abs(abbits - color_bits) > 1) {
		error("%s: Could not set requested exact bpp mode", __func__);
		XFree(vis_info);
		XCloseDisplay(dpy);
		return false;
	}

	// now if we don't have DONT_CARE_DEPTH in the dont_care_flags check for 
	// exact depth buffer format, however consider 24 and 32 bit the same
	if(!(gparams->dont_care_flags & DONT_CARE_DEPTH) && azbits != zbits) {
		if(!(zbits == 32 && azbits == 24 || zbits == 24 && azbits == 32)) {
			error("%s: Could not set requested exact zbuffer depth", __func__);
			XFree(vis_info);
			XCloseDisplay(dpy);
			return false;
		}
	}

	// if we don't have DONT_CARE_STENCIL make sure we have the stencil format
	// that was asked.
	if(!(gparams->dont_care_flags & DONT_CARE_STENCIL) && astencilbits != gparams->stencil_bits) {
		error("%s: Could not set exact stencil format", __func__);
		XFree(vis_info);
		XCloseDisplay(dpy);
		return false;
	}

	// everything is ok, create the context
	if(!(glx_ctx = glXCreateContext(dpy, vis_info, 0, True))) {
		error("%s: Failed to create GLX context", __func__);
		XFree(vis_info);
		XCloseDisplay(dpy);
		return false;
	}

	XSetWindowAttributes xattr;
	xattr.background_pixel = xattr.border_pixel = BlackPixel(dpy, screen);
	xattr.colormap = XCreateColormap(dpy, root_win, vis_info->visual, AllocNone);

	if(gparams->fullscreen) {
		// TODO: also test for "XFree86-VidModeExtension"
#ifdef USE_XF86VIDMODE
		info("Using XF86VidMode extension for fullscreen resolution switch.");
		
		XF86VidModeModeInfo **modes;
		XF86VidModeModeInfo *vid_mode = 0;
		int mode_count;
		
		XF86VidModeGetAllModeLines(dpy, screen, &mode_count, &modes);
		orig_mode = *modes[0];

		for(int i=0; i<mode_count; i++) {
			if(modes[i]->hdisplay == gparams->x && modes[i]->vdisplay == gparams->y) {
				vid_mode = modes[i];
			}
		}
		if(!vid_mode) {
			error("Could not set requested video mode");
			XFree(modes);
			XFree(vis_info);
			XCloseDisplay(dpy);
			return -1;
		}
		
		XF86VidModeSwitchToMode(dpy, screen, vid_mode);
		XF86VidModeSetViewPort(dpy, screen, 0, 0);
		XFree(modes);

		xattr.override_redirect = True;
		win = XCreateWindow(dpy, root_win, 0, 0, gparams->x, gparams->y, 0, vis_info->depth,
				InputOutput, vis_info->visual, CWColormap | CWBackPixel | CWBorderPixel | CWOverrideRedirect, &xattr);

		XWarpPointer(dpy, None, win, 0, 0, 0, 0, 0, 0);
		XMapRaised(dpy, win);
        XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync, CurrentTime);
        XGrabPointer(dpy, win, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, win, None, CurrentTime);
#else
		info("Resolution switching is not compiled or not supported by the X server, using a full-screen window.");

		XWindowAttributes root_attr;
		XGetWindowAttributes(dpy, root_win, &root_attr);

		gparams->x = root_attr.width;
		gparams->y = root_attr.height;
		xattr.override_redirect = True;
		win = XCreateWindow(dpy, root_win, 0, 0, gparams->x, gparams->y, 0, vis_info->depth,
				InputOutput, vis_info->visual, CWColormap | CWBackPixel | CWBorderPixel | CWOverrideRedirect, &xattr);

		XWarpPointer(dpy, None, win, 0, 0, 0, 0, 0, 0);
		XMapRaised(dpy, win);
        XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync, CurrentTime);
        XGrabPointer(dpy, win, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, win, None, CurrentTime);
#endif	// USE_XF86VIDMODE

		fullscreen = true;
	} else {
		win = XCreateWindow(dpy, root_win, 0, 0, gparams->x, gparams->y, 0, vis_info->depth,
				InputOutput, vis_info->visual, CWColormap | CWBackPixel | CWBorderPixel, &xattr);
	}

	long events = ExposureMask | StructureNotifyMask | KeyPressMask;	// expose and key events
	events |= ButtonPressMask | ButtonReleaseMask | PointerMotionMask;	// mouse events
	XSelectInput(dpy, win, events);
		
	// set WM cooperation settings
	Atom wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", True);
	XSetWMProtocols(dpy, win, &wm_delete, 1);

	XTextProperty tp_wname;
	static char *win_title = "3dengfx/X";
	XStringListToTextProperty(&win_title, 1, &tp_wname);
	XSetWMName(dpy, win, &tp_wname);
	XFree(tp_wname.value);

	XClassHint class_hint;
	class_hint.res_name = "3dengfx";
	class_hint.res_class = "3dengfx_graphics";
	XSetClassHint(dpy, win, &class_hint);

	XFree(vis_info);

	if(glXMakeCurrent(dpy, win, glx_ctx) == False) {
		error("%s: Failed to make the GLX context current", __func__);
		glXDestroyContext(dpy, glx_ctx);
		XDestroyWindow(dpy, win);
		XCloseDisplay(dpy);
		return false;
	}

	if(!glXIsDirect(dpy, glx_ctx)) {
		warning("using indirect rendering, which might be slow...");
	}

	XMapWindow(dpy, win);
	XFlush(dpy);

	fxwt_x_dpy = dpy;
	fxwt_x_win = win;
	
	return true;
}
Пример #24
0
/* FIXME: bits is currently unused */
Bool createGLWindow(char* title, int width, int height, int bits,
                    Bool fullscreenflag)
{
    XVisualInfo *vi;
    Colormap cmap;
    int dpyWidth, dpyHeight;
    int i;
    int glxMajorVersion, glxMinorVersion;
    int vidModeMajorVersion, vidModeMinorVersion;
    XF86VidModeModeInfo **modes;
    int modeNum;
    int bestMode;
    Atom wmDelete;
    Window winDummy;
    unsigned int borderDummy;
    
    GLWin.fs = fullscreenflag;
    /* set best mode to current */
    bestMode = 0;
    /* get a connection */
    GLWin.dpy = XOpenDisplay(0);
    GLWin.screen = DefaultScreen(GLWin.dpy);
    XF86VidModeQueryVersion(GLWin.dpy, &vidModeMajorVersion,
        &vidModeMinorVersion);
    printf("XF86VidModeExtension-Version %d.%d\n", vidModeMajorVersion,
        vidModeMinorVersion);
    XF86VidModeGetAllModeLines(GLWin.dpy, GLWin.screen, &modeNum, &modes);
    /* save desktop-resolution before switching modes */
    GLWin.deskMode = *modes[0];
    /* look for mode with requested resolution */
    for (i = 0; i < modeNum; i++)
    {
        if ((modes[i]->hdisplay == width) && (modes[i]->vdisplay == height))
        {
            bestMode = i;
        }
    }
    /* get an appropriate visual */
    vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListDbl);
    if (vi == NULL)
    {
        vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListSgl);
        printf("Only Singlebuffered Visual!\n");
    }
    else
    {
        printf("Got Doublebuffered Visual!\n");
    }
    glXQueryVersion(GLWin.dpy, &glxMajorVersion, &glxMinorVersion);
    printf("glX-Version %d.%d\n", glxMajorVersion, glxMinorVersion);
    /* create a GLX context */
    GLWin.ctx = glXCreateContext(GLWin.dpy, vi, 0, GL_TRUE);
    /* create a color map */
    cmap = XCreateColormap(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen),
        vi->visual, AllocNone);
    GLWin.attr.colormap = cmap;
    GLWin.attr.border_pixel = 0;

    if (GLWin.fs)
    {
        XF86VidModeSwitchToMode(GLWin.dpy, GLWin.screen, modes[bestMode]);
        XF86VidModeSetViewPort(GLWin.dpy, GLWin.screen, 0, 0);
        dpyWidth = modes[bestMode]->hdisplay;
        dpyHeight = modes[bestMode]->vdisplay;
        printf("Resolution %dx%d\n", dpyWidth, dpyHeight);
        XFree(modes);
    
        /* create a fullscreen window */
        GLWin.attr.override_redirect = True;
        GLWin.attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask |
            StructureNotifyMask;
        GLWin.win = XCreateWindow(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen),
            0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual,
            CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect,
            &GLWin.attr);
        XWarpPointer(GLWin.dpy, None, GLWin.win, 0, 0, 0, 0, 0, 0);
		XMapRaised(GLWin.dpy, GLWin.win);
        XGrabKeyboard(GLWin.dpy, GLWin.win, True, GrabModeAsync,
            GrabModeAsync, CurrentTime);
        XGrabPointer(GLWin.dpy, GLWin.win, True, ButtonPressMask,
            GrabModeAsync, GrabModeAsync, GLWin.win, None, CurrentTime);
    }
    else
    {
        /* create a window in window mode*/
        GLWin.attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask |
            StructureNotifyMask;
        GLWin.win = XCreateWindow(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen),
            0, 0, width, height, 0, vi->depth, InputOutput, vi->visual,
            CWBorderPixel | CWColormap | CWEventMask, &GLWin.attr);
        /* only set window title and handle wm_delete_events if in windowed mode */
        wmDelete = XInternAtom(GLWin.dpy, "WM_DELETE_WINDOW", True);
        XSetWMProtocols(GLWin.dpy, GLWin.win, &wmDelete, 1);
        XSetStandardProperties(GLWin.dpy, GLWin.win, title,
            title, None, NULL, 0, NULL);
        XMapRaised(GLWin.dpy, GLWin.win);
    }       
    /* connect the glx-context to the window */
    glXMakeCurrent(GLWin.dpy, GLWin.win, GLWin.ctx);
    XGetGeometry(GLWin.dpy, GLWin.win, &winDummy, &GLWin.x, &GLWin.y,
        &GLWin.width, &GLWin.height, &borderDummy, &GLWin.depth);
    printf("Depth %d\n", GLWin.depth);
    if (glXIsDirect(GLWin.dpy, GLWin.ctx)) 
        printf("Congrats, you have Direct Rendering!\n");
    else
        printf("Sorry, no Direct Rendering possible!\n");
    initGL();
    return True;    
}
Пример #25
0
/*!***********************************************************************
 @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;
}
Пример #26
0
static int config(uint32_t width, uint32_t height,
                       uint32_t d_width, uint32_t d_height,
                       uint32_t flags, char *title, uint32_t format)
{

    int x_off, y_off;
    int wanted_width, wanted_height;

    static unsigned char *vo_dga_base;
    static int prev_width, prev_height;

#ifdef HAVE_DGA2
    // needed to change DGA video mode
    int mX = VO_DGA_INVALID_RES, mY = VO_DGA_INVALID_RES, mVBI =
        100000, mMaxY = 0, i, j = 0;
    int dga_modenum;
    XDGAMode *modeline;
    XDGADevice *dgadevice;
#else
#ifdef HAVE_XF86VM
    unsigned int vm_event, vm_error;
    unsigned int vm_ver, vm_rev;
    int i, j = 0, have_vm = 0;
    int mX = VO_DGA_INVALID_RES, mY = VO_DGA_INVALID_RES, mVBI =
        100000, mMaxY = 0, dga_modenum;
#endif
    int bank, ram;
#endif

    vo_dga_src_format = format;

    wanted_width = d_width;
    wanted_height = d_height;

    if (!wanted_height)
        wanted_height = height;
    if (!wanted_width)
        wanted_width = width;

    if (!vo_dbpp)
    {
        if ((format & IMGFMT_BGR_MASK) == IMGFMT_BGR)
        {
            vo_dga_src_mode = vd_ModeValid(format & 0xff);
        }
    } else
    {
        vo_dga_src_mode = vd_ModeValid(vo_dbpp);
    }
    vo_dga_hw_mode = SRC_MODE.vdm_hw_mode;

    if (!vo_dga_src_mode)
    {
        mp_msg(MSGT_VO, MSGL_ERR, "vo_dga: unsupported video format!\n");
        return 1;
    }

    vo_dga_vp_width = vo_screenwidth;
    vo_dga_vp_height = vo_screenheight;

    mp_msg(MSGT_VO, MSGL_V, "vo_dga: XServer res: %dx%d\n",
           vo_dga_vp_width, vo_dga_vp_height);

// choose a suitable mode ...

#ifdef HAVE_DGA2
// Code to change the video mode added by Michael Graffam
// [email protected]

    mp_msg(MSGT_VO, MSGL_V, "vo_dga: vo_modelines=%p, vo_modecount=%d\n",
           vo_modelines, vo_modecount);

    if (vo_modelines == NULL)
    {
        mp_msg(MSGT_VO, MSGL_ERR, "vo_dga: can't get modelines\n");
        return 1;
    }

    mp_msg(MSGT_VO, MSGL_INFO,
           "vo_dga: DGA 2.0 available :-) Can switch resolution AND depth!\n");
    for (i = 0; i < vo_modecount; i++)
    {
        if (vd_ModeEqual(vo_modelines[i].depth,
                         vo_modelines[i].bitsPerPixel,
                         vo_modelines[i].redMask,
                         vo_modelines[i].greenMask,
                         vo_modelines[i].blueMask, vo_dga_hw_mode))
        {

            mp_msg(MSGT_VO, MSGL_V, "maxy: %4d, depth: %2d, %4dx%4d, ",
                   vo_modelines[i].maxViewportY, vo_modelines[i].depth,
                   vo_modelines[i].imageWidth,
                   vo_modelines[i].imageHeight);
            if (check_res
                (i, wanted_width, wanted_height, vo_modelines[i].depth,
                 vo_modelines[i].viewportWidth,
                 vo_modelines[i].viewportHeight,
                 (unsigned) vo_modelines[i].verticalRefresh,
                 vo_modelines[i].maxViewportY, &mX, &mY, &mVBI, &mMaxY))
                j = i;
        }
    }
    mp_msg(MSGT_VO, MSGL_INFO,
           "vo_dga: Selected hardware mode %4d x %4d @ %3d Hz @ depth %2d, bitspp %2d.\n",
           mX, mY, mVBI, HW_MODE.vdm_depth, HW_MODE.vdm_bitspp);
    mp_msg(MSGT_VO, MSGL_INFO,
           "vo_dga: Video parameters by codec: %3d x %3d, depth %2d, bitspp %2d.\n",
           width, height, SRC_MODE.vdm_depth, SRC_MODE.vdm_bitspp);
    vo_dga_vp_width = mX;
    vo_dga_vp_height = mY;

    if ((flags & VOFLAG_SWSCALE) || (flags & VOFLAG_FULLSCREEN))
    {                           /* -zoom or -fs */
        scale_dstW = (d_width + 7) & ~7;
        scale_dstH = d_height;
        scale_srcW = width;
        scale_srcH = height;
        aspect_save_screenres(mX, mY);
        aspect_save_orig(scale_srcW, scale_srcH);
        aspect_save_prescale(scale_dstW, scale_dstH);
        if (flags & VOFLAG_FULLSCREEN)       /* -fs */
            aspect(&scale_dstW, &scale_dstH, A_ZOOM);
        else if (flags & VOFLAG_SWSCALE)  /* -fs */
            aspect(&scale_dstW, &scale_dstH, A_NOZOOM);
        mp_msg(MSGT_VO, MSGL_INFO,
               "vo_dga: Aspect corrected size for SwScaler: %4d x %4d.\n",
               scale_dstW, scale_dstH);
        /* XXX this is a hack, but I'm lazy ;-) :: atmos */
        width = scale_dstW;
        height = scale_dstH;
    }

    vo_dga_width = vo_modelines[j].bytesPerScanline / HW_MODE.vdm_bytespp;
    dga_modenum = vo_modelines[j].num;
    modeline = vo_modelines + j;

#else

#ifdef HAVE_XF86VM

    mp_msg(MSGT_VO, MSGL_INFO,
           "vo_dga: DGA 1.0 compatibility code: Using XF86VidMode for mode switching!\n");

    if (XF86VidModeQueryExtension(mDisplay, &vm_event, &vm_error))
    {
        XF86VidModeQueryVersion(mDisplay, &vm_ver, &vm_rev);
        mp_msg(MSGT_VO, MSGL_INFO,
               "vo_dga: XF86VidMode Extension v%i.%i\n", vm_ver, vm_rev);
        have_vm = 1;
    } else
    {
        mp_msg(MSGT_VO, MSGL_ERR,
               "vo_dga: XF86VidMode Extension not available.\n");
    }

#define GET_VREFRESH(dotclk, x, y)( (((dotclk)/(x))*1000)/(y) )

    if (have_vm)
    {
        int modecount;

        XF86VidModeGetAllModeLines(mDisplay, mScreen, &modecount,
                                   &vo_dga_vidmodes);

        if (vo_dga_vidmodes != NULL)
        {
            for (i = 0; i < modecount; i++)
            {
                if (check_res(i, wanted_width, wanted_height,
                              vo_dga_modes[vo_dga_hw_mode].vdm_depth,
                              vo_dga_vidmodes[i]->hdisplay,
                              vo_dga_vidmodes[i]->vdisplay,
                              GET_VREFRESH(vo_dga_vidmodes[i]->dotclock,
                                           vo_dga_vidmodes[i]->htotal,
                                           vo_dga_vidmodes[i]->vtotal),
                              0, &mX, &mY, &mVBI, &mMaxY))
                    j = i;
            }

            mp_msg(MSGT_VO, MSGL_INFO,
                   "vo_dga: Selected video mode %4d x %4d @ %3d Hz @ depth %2d, bitspp %2d, video %3d x %3d.\n",
                   mX, mY, mVBI,
                   vo_dga_modes[vo_dga_hw_mode].vdm_depth,
                   vo_dga_modes[vo_dga_hw_mode].vdm_bitspp, width, height);
        } else
        {
            mp_msg(MSGT_VO, MSGL_INFO,
                   "vo_dga: XF86VidMode returned no screens - using current resolution.\n");
        }
        dga_modenum = j;
        vo_dga_vp_width = mX;
        vo_dga_vp_height = mY;
    }

#else
    mp_msg(MSGT_VO, MSGL_INFO,
           "vo_dga: Only have DGA 1.0 extension and no XF86VidMode :-(\n");
    mp_msg(MSGT_VO, MSGL_INFO,
           "        Thus, resolution switching is NOT possible.\n");

#endif
#endif

    vo_dga_src_width = width;
    vo_dga_src_height = height;

    if (vo_dga_src_width > vo_dga_vp_width ||
        vo_dga_src_height > vo_dga_vp_height)
    {
        mp_msg(MSGT_VO, MSGL_ERR,
               "vo_dga: Sorry, video larger than viewport is not yet supported!\n");
        // ugly, do something nicer in the future ...
#ifndef HAVE_DGA2
#ifdef HAVE_XF86VM
        if (vo_dga_vidmodes)
        {
            XFree(vo_dga_vidmodes);
            vo_dga_vidmodes = NULL;
        }
#endif
#endif
        return 1;
    }

    if (vo_dga_vp_width == VO_DGA_INVALID_RES)
    {
        mp_msg(MSGT_VO, MSGL_ERR,
               "vo_dga: Something is wrong with your DGA. There doesn't seem to be a\n"
               "         single suitable mode!\n"
               "         Please file a bug report (see DOCS/HTML/en/bugreports.html)\n");
#ifndef HAVE_DGA2
#ifdef HAVE_XF86VM
        if (vo_dga_vidmodes)
        {
            XFree(vo_dga_vidmodes);
            vo_dga_vidmodes = NULL;
        }
#endif
#endif
        return 1;
    }
// now let's start the DGA thing 

    if (!vo_config_count || width != prev_width || height != prev_height)
    {
#ifdef HAVE_DGA2

        if (!XDGAOpenFramebuffer(mDisplay, mScreen))
        {
            mp_msg(MSGT_VO, MSGL_ERR,
                   "vo_dga: Framebuffer mapping failed!!!\n");
            return 1;
        }

        dgadevice = XDGASetMode(mDisplay, mScreen, dga_modenum);
        XDGASync(mDisplay, mScreen);

        vo_dga_base = dgadevice->data;
        XFree(dgadevice);

        XDGASetViewport(mDisplay, mScreen, 0, 0, XDGAFlipRetrace);

#else

#ifdef HAVE_XF86VM
        if (have_vm)
        {
            XF86VidModeLockModeSwitch(mDisplay, mScreen, 0);
            // Two calls are needed to switch modes on my ATI Rage 128. Why?
            // for riva128 one call is enough!
            XF86VidModeSwitchToMode(mDisplay, mScreen,
                                    vo_dga_vidmodes[dga_modenum]);
            XF86VidModeSwitchToMode(mDisplay, mScreen,
                                    vo_dga_vidmodes[dga_modenum]);
        }
#endif

        XF86DGAGetViewPortSize(mDisplay, mScreen,
                               &vo_dga_vp_width, &vo_dga_vp_height);

        XF86DGAGetVideo(mDisplay, mScreen,
                        (char **) &vo_dga_base, &vo_dga_width, &bank,
                        &ram);

        XF86DGADirectVideo(mDisplay, mScreen,
                           XF86DGADirectGraphics | XF86DGADirectMouse |
                           XF86DGADirectKeyb);

        XF86DGASetViewPort(mDisplay, mScreen, 0, 0);

#endif
    }
    // do some more checkings here ...

    mp_msg(MSGT_VO, MSGL_V,
           "vo_dga: bytes/line: %d, screen res: %dx%d, depth: %d, base: %p, bpp: %d\n",
           vo_dga_width, vo_dga_vp_width, vo_dga_vp_height,
           HW_MODE.vdm_bytespp, vo_dga_base, HW_MODE.vdm_bitspp);

    x_off = (vo_dga_vp_width - vo_dga_src_width) >> 1;
    y_off = (vo_dga_vp_height - vo_dga_src_height) >> 1;

    vo_dga_bytes_per_line = vo_dga_src_width * HW_MODE.vdm_bytespp;
    vo_dga_lines = vo_dga_src_height;

    vo_dga_src_offset = 0;
    vo_dga_vp_offset =
        (y_off * vo_dga_width + x_off) * HW_MODE.vdm_bytespp;

    vo_dga_vp_skip = (vo_dga_width - vo_dga_src_width) * HW_MODE.vdm_bytespp;   // todo

    mp_msg(MSGT_VO, MSGL_V, "vo_dga: vp_off=%d, vp_skip=%d, bpl=%d\n",
           vo_dga_vp_offset, vo_dga_vp_skip, vo_dga_bytes_per_line);


    XGrabKeyboard(mDisplay, DefaultRootWindow(mDisplay), True,
                  GrabModeAsync, GrabModeAsync, CurrentTime);
    if (vo_grabpointer)
        XGrabPointer(mDisplay, DefaultRootWindow(mDisplay), True,
                     ButtonPressMask, GrabModeAsync, GrabModeAsync,
                     None, None, CurrentTime);

    if (!vo_config_count || width != prev_width || height != prev_height)
    {
        init_video_buffers(vo_dga_base,
                           vo_dga_vp_height,
                           vo_dga_width * HW_MODE.vdm_bytespp,
#ifdef HAVE_DGA2
                           modeline->maxViewportY,
#else
                           vo_dga_vp_height,
#endif
                           vo_doublebuffering);
        prev_width = width;
        prev_height = height;
    }

    mp_msg(MSGT_VO, MSGL_V, "vo_dga: Using %d frame buffer%s.\n",
           vo_dga_nr_video_buffers,
           vo_dga_nr_video_buffers == 1 ? "" : "s");

    vo_dga_is_running = 1;
    return 0;
}
Пример #27
0
/*
 * Restores the previously remembered visual settings
 */
static void fghRestoreState( void )
{
#if TARGET_HOST_UNIX_X11

#   ifdef X_XF86VidModeGetAllModeLines
    /* Restore the remembered pointer position: */
    XWarpPointer(
        fgDisplay.Display, None, fgDisplay.RootWindow, 0, 0, 0, 0,
        fgDisplay.DisplayPointerX, fgDisplay.DisplayPointerY
    );

    /*
     * This highly depends on the XFree86 extensions,
     * not approved as X Consortium standards
     */

    if( fgDisplay.DisplayModeValid )
    {
        XF86VidModeModeInfo** displayModes;
        int i, displayModesCount;

        if( !XF86VidModeGetAllModeLines(
                 fgDisplay.Display,
                 fgDisplay.Screen,
                 &displayModesCount,
                 &displayModes ) )
        {
            fgWarning( "XF86VidModeGetAllModeLines failed" );
            return;
        }


        /*
         * Check every of the modes looking for one that matches our demands.
         * If we find one, switch to it and restore the remembered viewport.
         */
        for( i = 0; i < displayModesCount; i++ )
        {
            if(displayModes[ i ]->hdisplay == fgDisplay.DisplayMode.hdisplay &&
               displayModes[ i ]->vdisplay == fgDisplay.DisplayMode.vdisplay &&
               displayModes[ i ]->dotclock == fgDisplay.DisplayModeClock )
            {
                if( !XF86VidModeSwitchToMode(
                         fgDisplay.Display,
                         fgDisplay.Screen,
                         displayModes[ i ] ) )
                {
                    fgWarning( "XF86VidModeSwitchToMode failed" );
                    break;
                }

                if( !XF86VidModeSetViewPort(
                         fgDisplay.Display,
                         fgDisplay.Screen,
                         fgDisplay.DisplayViewPortX,
                         fgDisplay.DisplayViewPortY ) )
                    fgWarning( "XF86VidModeSetViewPort failed" );


                /*
                 * For the case this would be the last X11 call the application
                 * calls exit() we've to flush the X11 output queue to have the
                 * commands sent to the X server before the application exits.
                 */
                XFlush( fgDisplay.Display );

                break;
            }
        }
        XFree( displayModes );
    }

#   else
    /*
     * XXX warning fghRestoreState: missing XFree86 video mode extensions,
     * XXX game mode will not change screen resolution when activated
     */
#   endif

#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE

    /* Restore the previously rememebered desktop display settings */
    ChangeDisplaySettings( &fgDisplay.DisplayMode, 0 );

#endif
}
Пример #28
0
void S9xInitDisplay (int argc, char **argv)
{
	Screen			*scrn;
	XSetWindowAttributes	xattr;

	signal (SIGINT, quit);
	signal (SIGTERM, quit);

	if ((ourdisp = XOpenDisplay(NULL)) == NULL) {
		printf ("Can't connect to X server!\n");
		S9xExit ();
	}


	ourscreen = DefaultScreen (ourdisp);
	scrn = DefaultScreenOfDisplay (ourdisp);
	ourvideo.bitdepth = DefaultDepth (ourdisp, ourscreen);
	ourvideo.screendepth = ourvideo.bitdepth / 8;
	rootWindow = RootWindowOfScreen (scrn);

	xattr.override_redirect = True;
	inputwin = XCreateWindow (ourdisp, RootWindowOfScreen(scrn),
	                          10, 10, 100, 100, 0, 0, InputOutput,
	                          DefaultVisualOfScreen(scrn),
	                          CWOverrideRedirect, &xattr);
	XMapWindow (ourdisp, inputwin);

	ourvideo.height = HeightOfScreen (scrn);



	switch (ourvideo.bitdepth) {
		case  8:
			Settings.SixteenBit = FALSE;
			Settings.Transparency = FALSE;
			cmap = XCreateColormap (ourdisp, rootWindow,
			                        DefaultVisualOfScreen (scrn),
						AllocAll);
			XSetWindowColormap (ourdisp, inputwin, cmap);
			for (int i=0; i<256; i++) {
				colors[i].pixel = i;
				colors[i].flags = DoRed | DoGreen | DoBlue;
			}
			break;
		case 16:
			Settings.SixteenBit = TRUE;
			if (!Settings.ForceNoTransparency)
				Settings.Transparency = TRUE;
			break;
		case 24:
			if (is32or24 == 32) {
				ourvideo.bitdepth = 32;
				ourvideo.screendepth = 4;
			}
			Settings.SixteenBit = TRUE;
			if (!Settings.ForceNoTransparency)
				Settings.Transparency = TRUE;
			break;
		default:
			printf ("Color depth %d not supported!\n");
			S9xExit ();
			break;
	}
	printf ("Found %d bit display\n", ourvideo.bitdepth);

	XFree(scrn);

	XF86DGAGetVideo (ourdisp, ourscreen, &(ourvideo.vidMemBegin),
          	       &(ourvideo.width), &(ourvideo.banksize),
          	       &(ourvideo.memsize));

#ifdef USE_XF86VIDMODE
   {
	XF86VidModeModeInfo	**all_modes;
	int			mode_count;
	XF86VidModeModeLine	mod_tmp;
	int			dotclock_tmp;
	int			x;

	XF86VidModeGetModeLine (ourdisp, ourscreen, &dotclock_tmp, &mod_tmp);

	orig_mode = ModeLine2ModeInfo (mod_tmp, dotclock_tmp);
	if (orig_mode->hdisplay == 320 && orig_mode->vdisplay == 240) {
		mod320x240 = orig_mode;
	} else {
		XF86VidModeGetAllModeLines (ourdisp,ourscreen, &mode_count,
		                            &all_modes);
		for (x = 0; x < mode_count; x++)
			if (all_modes[x]->hdisplay == 320 &&
			    all_modes[x]->vdisplay == 240) {
				mod320x240 = (XF86VidModeModeInfo *) malloc (
				               sizeof(XF86VidModeModeInfo));
				*mod320x240 = *(all_modes[x]);
				break;
			} else
				XFree (all_modes[x]->c_private);

		if (mod320x240 == NULL) {
			printf ("No 320x240 mode available!\n");
			S9xExit ();
		}

	}
	XFree(all_modes);

   }
#endif

	GFX.Pitch = IMAGE_WIDTH * (Settings.SixteenBit ? 2 : 1);
	GFX.Screen = (uint8 *) malloc (IMAGE_HEIGHT * GFX.Pitch);

	if (Settings.Transparency)
		GFX.SubScreen = (uint8 *) malloc (IMAGE_HEIGHT * GFX.Pitch);

	switch (ourvideo.bitdepth) {
		case  8:
			mWide = IMAGE_WIDTH / 4;
			mHigh = IMAGE_HEIGHT;
			mEtoE = (ourvideo.width - IMAGE_WIDTH) /4;
			break;
		case 16:
			mWide = IMAGE_WIDTH / 2;
			mHigh = IMAGE_HEIGHT;
			mEtoE = (ourvideo.width - IMAGE_WIDTH) / 2;
			break;
		case 24:
			mWide = IMAGE_WIDTH;
			mHigh = IMAGE_HEIGHT;
			mEtoE = (ourvideo.width - IMAGE_WIDTH) * 3;
			break;
		case 32:
			mWide = IMAGE_WIDTH;
			mHigh = IMAGE_HEIGHT;
			mEtoE = (ourvideo.width - IMAGE_WIDTH) * 4;
		default:
			break;
	}
	ourvideo.scrnBegin = ourvideo.vidMemBegin + (320 - IMAGE_WIDTH) * ourvideo.screendepth / 2 + ourvideo.width * ourvideo.screendepth * 8;
}
Пример #29
0
/*
===============
GLX_Init
===============
*/
int GLX_Init(glimpParms_t a)
{
    int attrib[] =
    {
        GLX_RGBA,				// 0
        GLX_RED_SIZE, 8,		// 1, 2
        GLX_GREEN_SIZE, 8,		// 3, 4
        GLX_BLUE_SIZE, 8,		// 5, 6
        GLX_DOUBLEBUFFER,		// 7
        GLX_DEPTH_SIZE, 24,		// 8, 9
        GLX_STENCIL_SIZE, 8,	// 10, 11
        GLX_ALPHA_SIZE, 8, // 12, 13
        None
    };
    // these match in the array
#define ATTR_RED_IDX 2
#define ATTR_GREEN_IDX 4
#define ATTR_BLUE_IDX 6
#define ATTR_DEPTH_IDX 9
#define ATTR_STENCIL_IDX 11
#define ATTR_ALPHA_IDX 13
    Window root;
    XVisualInfo *visinfo;
    XSetWindowAttributes attr;
    XSizeHints sizehints;
    unsigned long mask;
    int colorbits, depthbits, stencilbits;
    int tcolorbits, tdepthbits, tstencilbits;
    int actualWidth, actualHeight;
    int i;
    const char *glstring;

    if ( !GLimp_OpenDisplay() )
    {
        return false;
    }

    common->Printf( "Initializing OpenGL display\n" );

    root = RootWindow( dpy, scrnum );

    actualWidth = glConfig.vidWidth;
    actualHeight = glConfig.vidHeight;

    // Get video mode list
    if ( !XF86VidModeQueryVersion( dpy, &vidmode_MajorVersion, &vidmode_MinorVersion ) )
    {
        vidmode_ext = false;
        common->Printf("XFree86-VidModeExtension not available\n");
    }
    else
    {
        vidmode_ext = true;
        common->Printf("Using XFree86-VidModeExtension Version %d.%d\n",
                       vidmode_MajorVersion, vidmode_MinorVersion);
    }

    GLX_TestDGA();

    if ( vidmode_ext )
    {
        int best_fit, best_dist, dist, x, y;

        XF86VidModeGetAllModeLines( dpy, scrnum, &num_vidmodes, &vidmodes );

        // Are we going fullscreen?  If so, let's change video mode
        if ( a.fullScreen )
        {
            best_dist = 9999999;
            best_fit = -1;

            for (i = 0; i < num_vidmodes; i++)
            {
                if (a.width > vidmodes[i]->hdisplay ||
                        a.height > vidmodes[i]->vdisplay)
                    continue;

                x = a.width - vidmodes[i]->hdisplay;
                y = a.height - vidmodes[i]->vdisplay;
                dist = (x * x) + (y * y);
                if (dist < best_dist)
                {
                    best_dist = dist;
                    best_fit = i;
                }
            }

            if (best_fit != -1)
            {
                actualWidth = vidmodes[best_fit]->hdisplay;
                actualHeight = vidmodes[best_fit]->vdisplay;

                // change to the mode
                XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]);
                vidmode_active = true;

                // Move the viewport to top left
                // FIXME: center?
                XF86VidModeSetViewPort(dpy, scrnum, 0, 0);

                common->Printf( "Free86-VidModeExtension Activated at %dx%d\n", actualWidth, actualHeight );

            }
            else
            {
                a.fullScreen = false;
                common->Printf( "Free86-VidModeExtension: No acceptable modes found\n" );
            }
        }
        else
        {
            common->Printf( "XFree86-VidModeExtension: not fullscreen, ignored\n" );
        }
    }
    // color, depth and stencil
    colorbits = 24;
    depthbits = 24;
    stencilbits = 8;

    for (i = 0; i < 16; i++)
    {
        // 0 - default
        // 1 - minus colorbits
        // 2 - minus depthbits
        // 3 - minus stencil
        if ((i % 4) == 0 && i)
        {
            // one pass, reduce
            switch (i / 4)
            {
            case 2:
                if (colorbits == 24)
                    colorbits = 16;
                break;
            case 1:
                if (depthbits == 24)
                    depthbits = 16;
                else if (depthbits == 16)
                    depthbits = 8;
            case 3:
                if (stencilbits == 24)
                    stencilbits = 16;
                else if (stencilbits == 16)
                    stencilbits = 8;
            }
        }

        tcolorbits = colorbits;
        tdepthbits = depthbits;
        tstencilbits = stencilbits;

        if ((i % 4) == 3)  		// reduce colorbits
        {
            if (tcolorbits == 24)
                tcolorbits = 16;
        }

        if ((i % 4) == 2)  		// reduce depthbits
        {
            if (tdepthbits == 24)
                tdepthbits = 16;
            else if (tdepthbits == 16)
                tdepthbits = 8;
        }

        if ((i % 4) == 1)  		// reduce stencilbits
        {
            if (tstencilbits == 24)
                tstencilbits = 16;
            else if (tstencilbits == 16)
                tstencilbits = 8;
            else
                tstencilbits = 0;
        }

        if (tcolorbits == 24)
        {
            attrib[ATTR_RED_IDX] = 8;
            attrib[ATTR_GREEN_IDX] = 8;
            attrib[ATTR_BLUE_IDX] = 8;
        }
        else
        {
            // must be 16 bit
            attrib[ATTR_RED_IDX] = 4;
            attrib[ATTR_GREEN_IDX] = 4;
            attrib[ATTR_BLUE_IDX] = 4;
        }

        attrib[ATTR_DEPTH_IDX] = tdepthbits;	// default to 24 depth
        attrib[ATTR_STENCIL_IDX] = tstencilbits;

        visinfo = qglXChooseVisual(dpy, scrnum, attrib);
        if (!visinfo)
        {
            continue;
        }

        common->Printf( "Using %d/%d/%d Color bits, %d Alpha bits, %d depth, %d stencil display.\n",
                        attrib[ATTR_RED_IDX], attrib[ATTR_GREEN_IDX],
                        attrib[ATTR_BLUE_IDX], attrib[ATTR_ALPHA_IDX],
                        attrib[ATTR_DEPTH_IDX],
                        attrib[ATTR_STENCIL_IDX]);

        glConfig.colorBits = tcolorbits;
        glConfig.depthBits = tdepthbits;
        glConfig.stencilBits = tstencilbits;
        break;
    }

    if (!visinfo)
    {
        common->Printf("Couldn't get a visual\n");
        return false;
    }
    // window attributes
    attr.background_pixel = BlackPixel(dpy, scrnum);
    attr.border_pixel = 0;
    attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
    attr.event_mask = X_MASK;
    if (vidmode_active)
    {
        mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore |
               CWEventMask | CWOverrideRedirect;
        attr.override_redirect = True;
        attr.backing_store = NotUseful;
        attr.save_under = False;
    }
    else
    {
        mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
    }

    win = XCreateWindow(dpy, root, 0, 0,
                        actualWidth, actualHeight,
                        0, visinfo->depth, InputOutput,
                        visinfo->visual, mask, &attr);

    XStoreName(dpy, win, GAME_NAME);

    // don't let the window be resized
    // FIXME: allow resize (win32 does)
    sizehints.flags = PMinSize | PMaxSize;
    sizehints.min_width = sizehints.max_width = actualWidth;
    sizehints.min_height = sizehints.max_height = actualHeight;

    XSetWMNormalHints(dpy, win, &sizehints);

    XMapWindow( dpy, win );

    if ( vidmode_active )
    {
        XMoveWindow( dpy, win, 0, 0 );
    }

    XFlush(dpy);
    XSync(dpy, False);
    ctx = qglXCreateContext(dpy, visinfo, NULL, True);
    XSync(dpy, False);

    // Free the visinfo after we're done with it
    XFree(visinfo);

    qglXMakeCurrent(dpy, win, ctx);

    glstring = (const char *) qglGetString(GL_RENDERER);
    common->Printf("GL_RENDERER: %s\n", glstring);

    glstring = (const char *) qglGetString(GL_EXTENSIONS);
    common->Printf("GL_EXTENSIONS: %s\n", glstring);

    // FIXME: here, software GL test

    glConfig.isFullscreen = a.fullScreen;

    if ( glConfig.isFullscreen )
    {
        Sys_GrabMouseCursor( true );
    }

    return true;
}
Пример #30
0
bool CreateWindowGL (GL_Window* window) {
	XVisualInfo *vi;
	Colormap cmap;
	int dpyWidth, dpyHeight;
	int i;
	int glxMajorVersion, glxMinorVersion;
	int vidModeMajorVersion, vidModeMinorVersion;
	XF86VidModeModeInfo **modes;
	int modeNum;
	int bestMode;
	Atom wmDelete;
	Window winDummy;
	unsigned int borderDummy;
	int x, y;

	bestMode = 0;

	window->init.dpy = XOpenDisplay( NULL );
	window->init.screen = DefaultScreen( window->init.dpy );
	XF86VidModeQueryVersion( window->init.dpy, &vidModeMajorVersion,
													 &vidModeMinorVersion );
	
	printf( "XF86VMExt-Version %d.%d\n",
					vidModeMajorVersion, vidModeMinorVersion );
	XF86VidModeGetAllModeLines( window->init.dpy, window->init.screen,
															&modeNum, &modes );
	window->init.deskMode = *modes[0];

	for( i=0;i<modeNum;i++ ) {
		if( (modes[i]->hdisplay == window->init.width) &&
				(modes[i]->vdisplay == window->init.height) )
			bestMode = i;
	}

	vi = glXChooseVisual( window->init.dpy, window->init.screen, attrListDbl );
	if( vi == NULL ) {
		vi = glXChooseVisual( window->init.dpy, window->init.screen, attrListSgl );
		window->init.doubleBuffered = false;
		printf( "Single Buffered visual\n" );
	} else {
		window->init.doubleBuffered = true;
		printf( "Double Buffered visual\n" );
	}

	glXQueryVersion( window->init.dpy, &glxMajorVersion, &glxMinorVersion );
	printf( "glx-version %d.%d\n", glxMajorVersion, glxMinorVersion );

	window->init.ctx = glXCreateContext( window->init.dpy, vi, 0, GL_TRUE );

	cmap = XCreateColormap( window->init.dpy,
													RootWindow( window->init.dpy, vi->screen ),
													vi->visual, AllocNone );
	window->init.attr.colormap = cmap;
	window->init.attr.border_pixel = 0;

	if( window->init.isFullScreen ) {
		XF86VidModeSwitchToMode( window->init.dpy, window->init.screen,
														 modes[bestMode] );
		XF86VidModeSetViewPort( window->init.dpy, window->init.screen, 0, 0 );
		dpyWidth = modes[bestMode]->hdisplay;
		dpyHeight = modes[bestMode]->vdisplay;
		XFree( modes );

		window->init.attr.override_redirect = true;
		window->init.attr.event_mask =
			ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask |
			ButtonReleaseMask | StructureNotifyMask | PointerMotionMask;
		window->init.win =
			XCreateWindow( window->init.dpy,
										 RootWindow( window->init.dpy, vi->screen ),
										 0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput,
										 vi->visual, CWBorderPixel | CWColormap | CWEventMask |
										 CWOverrideRedirect, &window->init.attr );
		XWarpPointer( window->init.dpy, None, window->init.win, 0, 0, 0, 0, 0, 0 );
		XMapRaised( window->init.dpy, window->init.win );
		XGrabKeyboard( window->init.dpy, window->init.win, True, GrabModeAsync,
									 GrabModeAsync, CurrentTime );
		XGrabPointer( window->init.dpy, window->init.win, True, ButtonPressMask,
									GrabModeAsync, GrabModeAsync, window->init.win, None,
									CurrentTime );
	} else {
		window->init.attr.event_mask =
			ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask |
			ButtonReleaseMask | StructureNotifyMask | PointerMotionMask;
		window->init.win =
			XCreateWindow( window->init.dpy,
										 RootWindow( window->init.dpy, vi->screen ),
										 0, 0, window->init.width, window->init.height,
										 0, vi->depth, InputOutput, vi->visual,
										 CWBorderPixel | CWColormap | CWEventMask,
										 &window->init.attr );
		wmDelete = XInternAtom( window->init.dpy, "WM_DELETE_WINDOW", True );
		XSetWMProtocols( window->init.dpy, window->init.win, &wmDelete, 1 );
		XSetStandardProperties( window->init.dpy, window->init.win,
														window->init.title, window->init.title, None, NULL,
														0, NULL );
		XMapRaised( window->init.dpy, window->init.win );
	}

	glXMakeCurrent( window->init.dpy, window->init.win, window->init.ctx );
	XGetGeometry( window->init.dpy, window->init.win, &winDummy, &x, &y,
								&window->init.width, &window->init.height, &borderDummy,
								&window->init.depth );
	
	if( glXIsDirect( window->init.dpy, window->init.ctx ) )
		printf( "Direct rendering\n" );
	else
		printf( "Not Direct rendering\n" );

	return true;
}