Exemplo n.º 1
0
/* Create auxiliary (toplevel) windows with the current visual */
static void create_aux_windows(_THIS)
{
    int x = 0, y = 0;
    char classname[1024];
    XSetWindowAttributes xattr;
    XWMHints *hints;
    unsigned long app_event_mask;
    int def_vis = (SDL_Visual == DefaultVisual(SDL_Display, SDL_Screen));

    /* Look up some useful Atoms */
    WM_DELETE_WINDOW = XInternAtom(SDL_Display, "WM_DELETE_WINDOW", False);

    /* Don't create any extra windows if we are being managed */
    if ( SDL_windowid ) {
	FSwindow = 0;
	WMwindow = SDL_strtol(SDL_windowid, NULL, 0);
        return;
    }

    if(FSwindow)
	XDestroyWindow(SDL_Display, FSwindow);

#if SDL_VIDEO_DRIVER_X11_XINERAMA
    if ( use_xinerama ) {
        x = xinerama_info.x_org;
        y = xinerama_info.y_org;
    }
#endif
    xattr.override_redirect = True;
    xattr.background_pixel = def_vis ? BlackPixel(SDL_Display, SDL_Screen) : 0;
    xattr.border_pixel = 0;
    xattr.colormap = SDL_XColorMap;

    FSwindow = XCreateWindow(SDL_Display, SDL_Root,
                             x, y, 32, 32, 0,
			     this->hidden->depth, InputOutput, SDL_Visual,
			     CWOverrideRedirect | CWBackPixel | CWBorderPixel
			     | CWColormap,
			     &xattr);

    XSelectInput(SDL_Display, FSwindow, StructureNotifyMask);

    /* Tell KDE to keep the fullscreen window on top */
    {
	XEvent ev;
	long mask;

	SDL_memset(&ev, 0, sizeof(ev));
	ev.xclient.type = ClientMessage;
	ev.xclient.window = SDL_Root;
	ev.xclient.message_type = XInternAtom(SDL_Display,
					      "KWM_KEEP_ON_TOP", False);
	ev.xclient.format = 32;
	ev.xclient.data.l[0] = FSwindow;
	ev.xclient.data.l[1] = CurrentTime;
	mask = SubstructureRedirectMask;
	XSendEvent(SDL_Display, SDL_Root, False, mask, &ev);
    }

    hints = NULL;
    if(WMwindow) {
	/* All window attributes must survive the recreation */
	hints = XGetWMHints(SDL_Display, WMwindow);
	XDestroyWindow(SDL_Display, WMwindow);
    }

    /* Create the window for windowed management */
    /* (reusing the xattr structure above) */
    WMwindow = XCreateWindow(SDL_Display, SDL_Root,
                             x, y, 32, 32, 0,
			     this->hidden->depth, InputOutput, SDL_Visual,
			     CWBackPixel | CWBorderPixel | CWColormap,
			     &xattr);

    /* Set the input hints so we get keyboard input */
    if(!hints) {
	hints = XAllocWMHints();
	hints->input = True;
	hints->flags = InputHint;
    }
    XSetWMHints(SDL_Display, WMwindow, hints);
    XFree(hints);
    X11_SetCaptionNoLock(this, this->wm_title, this->wm_icon);

    app_event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask
	| PropertyChangeMask | StructureNotifyMask | KeymapStateMask;
    XSelectInput(SDL_Display, WMwindow, app_event_mask);

    /* Set the class hints so we can get an icon (AfterStep) */
    get_classname(classname, sizeof(classname));
    {
	XClassHint *classhints;
	classhints = XAllocClassHint();
	if(classhints != NULL) {
	    classhints->res_name = classname;
	    classhints->res_class = classname;
	    XSetClassHint(SDL_Display, WMwindow, classhints);
	    XFree(classhints);
	}
    }

	/* Setup the communication with the IM server */
	/* create_aux_windows may be called several times against the same
	   Display.  We should reuse the SDL_IM if one has been opened for
	   the Display, so we should not simply reset SDL_IM here.  */

	#ifdef X_HAVE_UTF8_STRING
	if (SDL_X11_HAVE_UTF8) {
		/* Discard obsolete resources if any.  */
		if (SDL_IM != NULL && SDL_Display != XDisplayOfIM(SDL_IM)) {
			/* Just a double check. I don't think this
		           code is ever executed. */
			SDL_SetError("display has changed while an IM is kept");
			if (SDL_IC) {
				XUnsetICFocus(SDL_IC);
				XDestroyIC(SDL_IC);
				SDL_IC = NULL;
			}
			XCloseIM(SDL_IM);
			SDL_IM = NULL;
		}

		/* Open an input method.  */
		if (SDL_IM == NULL) {
			char *old_locale = NULL, *old_modifiers = NULL;
			const char *p;
			size_t n;
			/* I'm not comfortable to do locale setup
			   here.  However, we need C library locale
			   (and xlib modifiers) to be set based on the
			   user's preference to use XIM, and many
			   existing game programs doesn't take care of
			   users' locale preferences, so someone other
			   than the game program should do it.
			   Moreover, ones say that some game programs
			   heavily rely on the C locale behaviour,
			   e.g., strcol()'s, and we can't change the C
			   library locale.  Given the situation, I
			   couldn't find better place to do the
			   job... */

			/* Save the current (application program's)
			   locale settings.  */
			p = setlocale(LC_ALL, NULL);
			if ( p ) {
				n = SDL_strlen(p)+1;
				old_locale = SDL_stack_alloc(char, n);
				if ( old_locale ) {
					SDL_strlcpy(old_locale, p, n);
				}
			}
			p = XSetLocaleModifiers(NULL);
			if ( p ) {
				n = SDL_strlen(p)+1;
				old_modifiers = SDL_stack_alloc(char, n);
				if ( old_modifiers ) {
					SDL_strlcpy(old_modifiers, p, n);
				}
			}

			/* Fetch the user's preferences and open the
			   input method with them.  */
			setlocale(LC_ALL, "");
			XSetLocaleModifiers("");
			SDL_IM = XOpenIM(SDL_Display, NULL, classname, classname);

			/* Restore the application's locale settings
			   so that we don't break the application's
			   expected behaviour.  */
			if ( old_locale ) {
				/* We need to restore the C library
				   locale first, since the
				   interpretation of the X modifier
				   may depend on it.  */
				setlocale(LC_ALL, old_locale);
				SDL_stack_free(old_locale);
			}
			if ( old_modifiers ) {
				XSetLocaleModifiers(old_modifiers);
				SDL_stack_free(old_modifiers);
			}
		}

		/* Create a new input context for the new window just created.  */
		if (SDL_IM == NULL) {
			SDL_SetError("no input method could be opened");
		} else {
			if (SDL_IC != NULL) {
				/* Discard the old IC before creating new one.  */
			    XUnsetICFocus(SDL_IC);
			    XDestroyIC(SDL_IC);
			}
			/* Theoretically we should check the current IM supports
			   PreeditNothing+StatusNothing style (i.e., root window method)
			   before creating the IC.  However, it is the bottom line method,
			   and we supports any other options.  If the IM didn't support
			   root window method, the following call fails, and SDL falls
			   back to pre-XIM keyboard handling.  */
			SDL_IC = pXCreateIC(SDL_IM,
					XNClientWindow, WMwindow,
					XNFocusWindow, WMwindow,
					XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
					XNResourceName, classname,
					XNResourceClass, classname,
					NULL);

			if (SDL_IC == NULL) {
				SDL_SetError("no input context could be created");
				XCloseIM(SDL_IM);
				SDL_IM = NULL;
			} else {
				/* We need to receive X events that an IM wants and to pass
				   them to the IM through XFilterEvent. The set of events may
				   vary depending on the IM implementation and the options
				   specified through various routes. Although unlikely, the
				   xlib specification allows IM to change the event requirement
				   with its own circumstances, it is safe to call SelectInput
				   whenever we re-create an IC.  */
				unsigned long mask = 0;
				char *ret = pXGetICValues(SDL_IC, XNFilterEvents, &mask, NULL);
				if (ret != NULL) {
					XUnsetICFocus(SDL_IC);
					XDestroyIC(SDL_IC);
					SDL_IC = NULL;
					SDL_SetError("no input context could be created");
					XCloseIM(SDL_IM);
					SDL_IM = NULL;
				} else {
					XSelectInput(SDL_Display, WMwindow, app_event_mask | mask);
					XSetICFocus(SDL_IC);
				}
			}
		}
	}
Exemplo n.º 2
0
void CL_Clipboard_X11::event_selection_request(XSelectionRequestEvent &xselectionrequest)
{
	XSelectionRequestEvent *rptr = &xselectionrequest;
	if (rptr->requestor == window) return;	// Ignore request if from self

	XEvent new_event;
	new_event.xselection.type = SelectionNotify;
	new_event.xselection.display = rptr->display;
	new_event.xselection.requestor = rptr->requestor;
	new_event.xselection.selection = rptr->selection;
	new_event.xselection.target = rptr->target;
	new_event.xselection.property = None;
	new_event.xselection.time = rptr->time;

	Atom xa_targets = XInternAtom(disp, "TARGETS", False);
	Atom xa_multiple = XInternAtom(disp, "MULTIPLE", False);

	struct AtomPair { Atom target; Atom property; } *multi_ptr = NULL;

	unsigned char *data_ptr = NULL;
	int num_multi = 0;
	int index_multi = -1;
	if (rptr->target == xa_multiple)
	{
		unsigned long number_items;
		int actual_format;
		Atom actual_type;
		data_ptr = x11_window->get_property( rptr->requestor, rptr->property, &number_items, &actual_format, &actual_type );
		if ( data_ptr )
		{
			num_multi = number_items / 2;
			multi_ptr = (struct AtomPair *) data_ptr;
		}
		index_multi = 0;
	}

	while( index_multi < num_multi)
	{
		Window xtarget;
		Atom xproperty;
		new_event.xselection.property = None;
		if (multi_ptr)
		{
			xtarget = multi_ptr[index_multi].target;
			xproperty = multi_ptr[index_multi].property;
			index_multi++;
		}else
		{
			xtarget = rptr->target;
			xproperty = rptr->property;
		}

		if (xtarget == xa_targets)
		{
			long new_targets[1];
			new_targets[0] = XA_STRING;
			XChangeProperty( disp, rptr->requestor, xproperty, xa_targets, 32, PropModeReplace, (unsigned char *) new_targets, 1);
			new_event.xselection.property = xproperty;
		}else
		{

			if (xtarget == XA_STRING)
			{
				XChangeProperty(disp, rptr->requestor, xproperty, xtarget, 8, PropModeReplace, (const unsigned char*) clipboard_current.c_str(), clipboard_current.size());
				new_event.xselection.property = xproperty;

			}
		}
		XSendEvent( disp, rptr->requestor, False, 0, &new_event );
		if (!num_multi) break;
	}
	if (data_ptr)
	{
		XFree(data_ptr);
	}
}
Exemplo n.º 3
0
/* FIXME: bits is currently unused */
Bool createGLWindow(const 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");
    if (!initGL())
    {
        printf("Could not initialize OpenGL.\nAborting...\n");
        return False;
    }        
    return True;    
}
Exemplo n.º 4
0
static gboolean
gst_gl_context_glx_create_context (GstGLContext * context,
    GstGLAPI gl_api, GstGLContext * other_context, GError ** error)
{
  GstGLContextGLX *context_glx;
  GstGLWindow *window;
  GstGLWindowX11 *window_x11;
  GstGLDisplay *display;
  gboolean create_context;
  const char *glx_exts;
  Display *device;
  guintptr external_gl_context = 0;

  context_glx = GST_GL_CONTEXT_GLX (context);
  window = gst_gl_context_get_window (context);
  window_x11 = GST_GL_WINDOW_X11 (window);
  display = gst_gl_context_get_display (context);

  if (other_context) {
    if (gst_gl_context_get_gl_platform (other_context) != GST_GL_PLATFORM_GLX) {
      g_set_error (error, GST_GL_CONTEXT_ERROR,
          GST_GL_CONTEXT_ERROR_WRONG_CONFIG,
          "Cannot share context with non-GLX context");
      goto failure;
    }

    external_gl_context = gst_gl_context_get_gl_context (other_context);
  }

  device = (Display *) gst_gl_display_get_handle (display);
  glx_exts = glXQueryExtensionsString (device, DefaultScreen (device));

  create_context = gst_gl_check_extension ("GLX_ARB_create_context", glx_exts);
  context_glx->priv->glXCreateContextAttribsARB =
      (gpointer) glXGetProcAddressARB ((const GLubyte *)
      "glXCreateContextAttribsARB");

  if (create_context && context_glx->priv->glXCreateContextAttribsARB) {
    gint i;

    for (i = 0; i < G_N_ELEMENTS (gl_versions); i++) {
      GstGLAPI selected_gl_api;
      gint profileMask = 0;
      gint contextFlags = 0;

      if (gl_api & GST_GL_API_OPENGL3 && (gl_versions[i].major > 3
              || (gl_versions[i].major == 3 && gl_versions[i].minor >= 2))) {
        profileMask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
        selected_gl_api = GST_GL_API_OPENGL3;
        contextFlags |= GLX_CONTEXT_DEBUG_BIT_ARB;
      } else {
        selected_gl_api = GST_GL_API_OPENGL;
      }

      GST_DEBUG_OBJECT (context, "trying to create a GL %d.%d context",
          gl_versions[i].major, gl_versions[i].minor);

      context_glx->glx_context = _create_context_with_flags (context_glx,
          device, context_glx->priv->fbconfigs[0],
          (GLXContext) external_gl_context, gl_versions[i].major,
          gl_versions[i].minor, contextFlags, profileMask);

      if (context_glx->glx_context) {
        context_glx->priv->context_api = selected_gl_api;
        break;
      }
    }
  } else {
    context_glx->glx_context =
        glXCreateContext (device, window_x11->visual_info,
        (GLXContext) external_gl_context, TRUE);
    context_glx->priv->context_api = GST_GL_API_OPENGL;
  }

  if (context_glx->priv->fbconfigs)
    XFree (context_glx->priv->fbconfigs);

  if (!context_glx->glx_context) {
    g_set_error (error, GST_GL_CONTEXT_ERROR,
        GST_GL_CONTEXT_ERROR_CREATE_CONTEXT, "Failed to create opengl context");
    goto failure;
  }

  GST_LOG ("gl context id: %ld", (gulong) context_glx->glx_context);

  gst_object_unref (window);
  gst_object_unref (display);

  return TRUE;

failure:
  if (window)
    gst_object_unref (window);
  gst_object_unref (display);

  return FALSE;
}
Exemplo n.º 5
0
void get_icon (Task *tsk)
{
	Panel *panel = tsk->area.panel;
	if (!panel->g_task.icon) return;
	size_t i;
	Imlib_Image img = NULL;
	XWMHints *hints = 0;
	gulong *data = 0;

	int k;
	for (k=0; k<TASK_STATE_COUNT; ++k) {
		if (tsk->icon[k]) {
			imlib_context_set_image(tsk->icon[k]);
			imlib_free_image();
			tsk->icon[k] = 0;
		}
	}

	data = server_get_property (tsk->win, server.atom._NET_WM_ICON, XA_CARDINAL, (int*)&i);
	if (data) {
		// get ARGB icon
		int w, h;
		gulong *tmp_data;

		tmp_data = get_best_icon (data, get_icon_count (data, i), i, &w, &h, panel->g_task.icon_size1);
#ifdef __x86_64__
		DATA32 icon_data[w * h];
		size_t length = w * h;
		for (i = 0; i < length; ++i)
			icon_data[i] =  tmp_data[i];
		img = imlib_create_image_using_copied_data (w, h, icon_data);
#else
		img = imlib_create_image_using_data (w, h, (DATA32*)tmp_data);
#endif
	}
	else {
		// get Pixmap icon
		hints = XGetWMHints(server.dsp, tsk->win);
		if (hints) {
			if (hints->flags & IconPixmapHint && hints->icon_pixmap != 0) {
				// get width, height and depth for the pixmap
				Window root;
				int  icon_x, icon_y;
				uint32_t border_width, bpp;
				uint32_t w, h;

				//printf("  get pixmap\n");
				XGetGeometry(server.dsp, hints->icon_pixmap, &root, &icon_x, &icon_y, &w, &h, &border_width, &bpp);
				imlib_context_set_drawable(hints->icon_pixmap);
				img = imlib_create_image_from_drawable(hints->icon_mask, 0, 0, w, h, 0);
			}
		}
	}
	if (img == NULL) {
		imlib_context_set_image(default_icon);
		img = imlib_clone_image();
	}

	// transform icons
	imlib_context_set_image(img);
	imlib_image_set_has_alpha(1);
	int w, h;
	w = imlib_image_get_width();
	h = imlib_image_get_height();
	Imlib_Image orig_image = imlib_create_cropped_scaled_image(0, 0, w, h, panel->g_task.icon_size1, panel->g_task.icon_size1);
	imlib_free_image();

	imlib_context_set_image(orig_image);
	tsk->icon_width = imlib_image_get_width();
	tsk->icon_height = imlib_image_get_height();
	for (k=0; k<TASK_STATE_COUNT; ++k) {
		imlib_context_set_image(orig_image);
		tsk->icon[k] = imlib_clone_image();
		imlib_context_set_image(tsk->icon[k]);
		DATA32 *data32;
		if (panel->g_task.alpha[k] != 100 || panel->g_task.saturation[k] != 0 || panel->g_task.brightness[k] != 0) {
			data32 = imlib_image_get_data();
			adjust_asb(data32, tsk->icon_width, tsk->icon_height, panel->g_task.alpha[k], (float)panel->g_task.saturation[k]/100, (float)panel->g_task.brightness[k]/100);
			imlib_image_put_back_data(data32);
		}
	}
	imlib_context_set_image(orig_image);
	imlib_free_image();

	if (hints)
		XFree(hints);
	if (data)
		XFree (data);

	GPtrArray* task_group = task_get_tasks(tsk->win);
	if (task_group) {
		for (i=0; i<task_group->len; ++i) {
			Task* tsk2 = g_ptr_array_index(task_group, i);
			tsk2->icon_width = tsk->icon_width;
			tsk2->icon_height = tsk->icon_height;
			int k;
			for (k=0; k<TASK_STATE_COUNT; ++k)
				tsk2->icon[k] = tsk->icon[k];
			set_task_redraw(tsk2);
		}
	}
}
	//-------------------------------------------------------------------------------------------------//
	void GLXWindow::create(const String& name, uint width, uint height,
			   bool fullScreen, const NameValuePairList *miscParams)
	{
		Display *xDisplay = mGLSupport->getXDisplay();
		String title = name;
		uint samples = 0;
		short frequency = 0;
		bool vsync = false;
		unsigned int vsyncInterval = 1;
		int gamma = 0;
		::GLXContext glxContext = 0;
		::GLXDrawable glxDrawable = 0;
		Window externalWindow = 0;
		Window parentWindow = DefaultRootWindow(xDisplay);
		int left = DisplayWidth(xDisplay, DefaultScreen(xDisplay))/2 - width/2;
		int top  = DisplayHeight(xDisplay, DefaultScreen(xDisplay))/2 - height/2;
		
		mIsFullScreen = fullScreen;
		
		if(miscParams)
		{
			NameValuePairList::const_iterator opt;
			NameValuePairList::const_iterator end = miscParams->end();
			
			// NB: Do not try to implement the externalGLContext option.
			//
			//	 Accepting a non-current context would expose us to the 
			//	 risk of segfaults when we made it current. Since the
			//	 application programmers would be responsible for these
			//	 segfaults, they are better discovering them in their code.
		
			if ((opt = miscParams->find("currentGLContext")) != end &&
				StringConverter::parseBool(opt->second))
			{
				if (! glXGetCurrentContext())
				{
					OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "currentGLContext was specified with no current GL context", "GLXWindow::create");
				}
				
				glxContext = glXGetCurrentContext();
				glxDrawable = glXGetCurrentDrawable();
			}
			
			// Note: Some platforms support AA inside ordinary windows
			if((opt = miscParams->find("FSAA")) != end) 
				samples = StringConverter::parseUnsignedInt(opt->second);
			
			if((opt = miscParams->find("displayFrequency")) != end) 
				frequency = (short)StringConverter::parseInt(opt->second);
			
			if((opt = miscParams->find("vsync")) != end) 
				vsync = StringConverter::parseBool(opt->second);

			if((opt = miscParams->find("vsyncInterval")) != end) 
				vsyncInterval = StringConverter::parseUnsignedInt(opt->second);

			if ((opt = miscParams->find("gamma")) != end)
				gamma = StringConverter::parseBool(opt->second);

			if((opt = miscParams->find("left")) != end) 
				left = StringConverter::parseInt(opt->second);
			
			if((opt = miscParams->find("top")) != end) 
				top = StringConverter::parseInt(opt->second);
			
			if((opt = miscParams->find("title")) != end) 
				title = opt->second;
			
			if ((opt = miscParams->find("externalGLControl")) != end)
				mIsExternalGLControl = StringConverter::parseBool(opt->second);
			
			if((opt = miscParams->find("parentWindowHandle")) != end) 
			{
				vector<String>::type tokens = StringUtil::split(opt->second, " :");
				
				if (tokens.size() == 3)
				{
					// deprecated display:screen:xid format
					parentWindow = StringConverter::parseUnsignedLong(tokens[2]);
				}
				else
				{
					// xid format
					parentWindow = StringConverter::parseUnsignedLong(tokens[0]);
				}
			}
			else if((opt = miscParams->find("externalWindowHandle")) != end) 
			{
				vector<String>::type tokens = StringUtil::split(opt->second, " :");
				
				LogManager::getSingleton().logMessage(
													  "GLXWindow::create: The externalWindowHandle parameter is deprecated.\n"
													  "Use the parentWindowHandle or currentGLContext parameter instead.");
				
				if (tokens.size() == 3)
				{
					// Old display:screen:xid format
					// The old GLX code always created a "parent" window in this case:
					parentWindow = StringConverter::parseUnsignedLong(tokens[2]);
				}
				else if (tokens.size() == 4)
				{
					// Old display:screen:xid:visualinfo format
					externalWindow = StringConverter::parseUnsignedLong(tokens[2]);
				}
				else
				{
					// xid format
					externalWindow = StringConverter::parseUnsignedLong(tokens[0]);
				}
			}
		}
		
		// Ignore fatal XErrorEvents during parameter validation:
		oldXErrorHandler = XSetErrorHandler(safeXErrorHandler);
		// Validate parentWindowHandle
		
		if (parentWindow != DefaultRootWindow(xDisplay))
		{
			XWindowAttributes windowAttrib;
			
			if (! XGetWindowAttributes(xDisplay, parentWindow, &windowAttrib) ||
				windowAttrib.root != DefaultRootWindow(xDisplay))
			{
				OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Invalid parentWindowHandle (wrong server or screen)", "GLXWindow::create");
			}
		}
		
		// Validate externalWindowHandle
		
		if (externalWindow != 0)
		{
			XWindowAttributes windowAttrib;
			
			if (! XGetWindowAttributes(xDisplay, externalWindow, &windowAttrib) ||
				windowAttrib.root != DefaultRootWindow(xDisplay))
			{
				OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Invalid externalWindowHandle (wrong server or screen)", "GLXWindow::create");
			}
			glxDrawable = externalWindow;
		}

		// Derive fbConfig
		
		::GLXFBConfig fbConfig = 0;
		
		if (glxDrawable)
		{
			fbConfig = mGLSupport->getFBConfigFromDrawable (glxDrawable, &width, &height);
		}

		if (! fbConfig && glxContext)
		{
			fbConfig = mGLSupport->getFBConfigFromContext (glxContext);
		}
			
		mIsExternal = (glxDrawable != 0);
		
		XSetErrorHandler(oldXErrorHandler);
		
		if (! fbConfig)
		{
			int minAttribs[] = {
				GLX_DRAWABLE_TYPE,  GLX_WINDOW_BIT,
				GLX_RENDER_TYPE,	GLX_RGBA_BIT,
				GLX_RED_SIZE,	   1,
				GLX_BLUE_SIZE,	  1,
				GLX_GREEN_SIZE,	 1,
				None
			};
			
			int maxAttribs[] = {
				GLX_SAMPLES,		samples,
				GLX_DOUBLEBUFFER,   1,
				GLX_STENCIL_SIZE,   INT_MAX,
				GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, 1,
				None
			};

			fbConfig = mGLSupport->selectFBConfig(minAttribs, maxAttribs);

			if (gamma != 0)
			{
				mGLSupport->getFBConfigAttrib(fbConfig, GL_FRAMEBUFFER_SRGB_CAPABLE_EXT, &gamma);
			}

			mHwGamma = (gamma != 0);
		}
		
    if (! fbConfig)
    {
      // This should never happen.
      OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unexpected failure to determine a GLXFBConfig","GLXWindow::create");
    }
		
		mIsTopLevel = (! mIsExternal && parentWindow == DefaultRootWindow(xDisplay));
		
		if (! mIsTopLevel)
		{
			mIsFullScreen = false;
			left = top = 0;
		}
		
		if (mIsFullScreen) 
		{
			mGLSupport->switchMode (width, height, frequency);
		}
		
		if (! mIsExternal)
		{
			XSetWindowAttributes attr;
			ulong mask;
			XVisualInfo *visualInfo = mGLSupport->getVisualFromFBConfig (fbConfig);
			
			attr.background_pixel = 0;
			attr.border_pixel = 0;
			attr.colormap = XCreateColormap(xDisplay, DefaultRootWindow(xDisplay), visualInfo->visual, AllocNone);
			attr.event_mask = StructureNotifyMask | VisibilityChangeMask | FocusChangeMask;
			mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
			
			if(mIsFullScreen && mGLSupport->mAtomFullScreen == None) 
			{
				LogManager::getSingleton().logMessage("GLXWindow::switchFullScreen: Your WM has no fullscreen support");
				
				// A second best approach for outdated window managers
				attr.backing_store = NotUseful;
				attr.save_under = False;
				attr.override_redirect = True;
				mask |= CWSaveUnder | CWBackingStore | CWOverrideRedirect;
				left = top = 0;
			} 
			
			// Create window on server
			mWindow = XCreateWindow(xDisplay, parentWindow, left, top, width, height, 0, visualInfo->depth, InputOutput, visualInfo->visual, mask, &attr);
			
			XFree(visualInfo);
			
			if(!mWindow) 
			{
				OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to create an X Window", "GLXWindow::create");
			}
			
			if (mIsTopLevel)
			{
				XWMHints *wmHints;
				XSizeHints *sizeHints;
				
				if ((wmHints = XAllocWMHints()) != NULL) 
				{
					wmHints->initial_state = NormalState;
					wmHints->input = True;
					wmHints->flags = StateHint | InputHint;
					
					int depth = DisplayPlanes(xDisplay, DefaultScreen(xDisplay));
					
					// Check if we can give it an icon
					if(depth == 24 || depth == 32) 
					{
						if(mGLSupport->loadIcon("GLX_icon.png", &wmHints->icon_pixmap, &wmHints->icon_mask))
						{
							wmHints->flags |= IconPixmapHint | IconMaskHint;
						}
					}
				}
				
				// Is this really necessary ? Which broken WM might need it?
				if ((sizeHints = XAllocSizeHints()) != NULL)
				{
					sizeHints->flags = USPosition;
				}
				
				XTextProperty titleprop;
				char *lst = (char*)title.c_str();
				XStringListToTextProperty((char **)&lst, 1, &titleprop);
				XSetWMProperties(xDisplay, mWindow, &titleprop, NULL, NULL, 0, sizeHints, wmHints, NULL);
				
				XFree(titleprop.value);
				XFree(wmHints);
				XFree(sizeHints);
				
				XSetWMProtocols(xDisplay, mWindow, &mGLSupport->mAtomDeleteWindow, 1);
				
				XWindowAttributes windowAttrib;
				
				XGetWindowAttributes(xDisplay, mWindow, &windowAttrib);
				
				left = windowAttrib.x;
				top = windowAttrib.y;
				width = windowAttrib.width;
				height = windowAttrib.height;
			}
			
			glxDrawable = mWindow;
			
			XMapWindow(xDisplay, mWindow);
			
			if (mIsFullScreen)
			{
				switchFullScreen (true);
			}
			XFlush(xDisplay);
			
			WindowEventUtilities::_addRenderWindow(this);
		}
		
    mContext = new GLXContext(mGLSupport, fbConfig, glxDrawable, glxContext);
		
		::GLXDrawable oldDrawable = glXGetCurrentDrawable();
		::GLXContext  oldContext  = glXGetCurrentContext();
		
		mContext->setCurrent();
		
		if (! mIsExternalGLControl && GLXEW_SGI_swap_control)
		{
			glXSwapIntervalSGI (vsync ? vsyncInterval : 0);
		}
		
		mContext->endCurrent();
		
		glXMakeCurrent (mGLSupport->getGLDisplay(), oldDrawable, oldContext);
		
		int fbConfigID;
		
		mGLSupport->getFBConfigAttrib(fbConfig, GLX_FBCONFIG_ID, &fbConfigID);
		
		LogManager::getSingleton().logMessage("GLXWindow::create used FBConfigID = " + StringConverter::toString(fbConfigID));
		
		mName = name;
		mWidth = width;
		mHeight = height;
		mLeft = left;
		mTop = top;
		mActive = true;
		mClosed = false;
	}
Exemplo n.º 7
0
	void GlXOffscreenContext::createContext()
	{
		_ready = false;

		_display = XOpenDisplay(NULL);

		if (!_display)
			localError("Unable to open XDisplay.");

		int errorBase, eventBase;
		if (!glXQueryExtension(_display, &errorBase, &eventBase))
			localError("OpenGL GLX Extension not supported.");

		int screen = DefaultScreen(_display);

		int glxVersionMajor, glxVersionMinor;
		glXQueryVersion(_display, &glxVersionMajor, &glxVersionMinor);

		dbg << "GLX Version: " << glxVersionMajor << "." << glxVersionMinor << endl;

		int fbConfigCount = 0;

		int attribList[] =
		{
			//GLX_X_RENDERABLE, True, // Implied
			GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,// | GLX_WINDOW_BIT,
			GLX_RENDER_TYPE, GLX_RGBA_BIT,
			GLX_RED_SIZE, 8,
			GLX_BLUE_SIZE, 8,
			GLX_GREEN_SIZE, 8,
			//GLX_ALPHA_SIZE, 8,
			//GLX_MAX_PBUFFER_WIDTH, _width,
			//GLX_MAX_PBUFFER_HEIGHT, _height,
			GLX_DEPTH_SIZE, 24,
			GLX_DOUBLEBUFFER, False,
			None
		};

		GLXFBConfig* fbConfigs = glXChooseFBConfig(_display, screen, attribList, &fbConfigCount);

		if ((fbConfigs == NULL) || (fbConfigCount <= 0))
			localError("Unable to choose fb config.");

		int pBufferAttribList[] =
		{
			GLX_PBUFFER_WIDTH, (int)_width,
			GLX_PBUFFER_HEIGHT, (int)_height,
			GLX_LARGEST_PBUFFER, False,
			None
		};

		for (int i = 0; i < fbConfigCount; ++i)
		{
			_pBuffer = glXCreatePbuffer(_display, fbConfigs[i], pBufferAttribList);

			if (_pBuffer != None)
			{
				dbg << "Found successful frame buffer on attempt " << (i+1) << ".." << endl;
				_fbConfig = fbConfigs[i];
				break;
			}
		}

		XSync(_display, False);

		XFree(fbConfigs);

		if (_pBuffer == None)
			localError("Unable to create pbuffer.");

		// Get visual..
		XVisualInfo* visInfo = glXGetVisualFromFBConfig(_display, _fbConfig);
		if (!visInfo)
		{
			localError("Unable to get X visual.");
		}

		// Create context..
		_context = glXCreateContext(_display, visInfo, NULL, True);

		if (!_context)
		{
			dbg << "Unable to create a direct context, attempting indirect one.." << endl;
			_context = glXCreateContext(_display, visInfo, NULL, False);
		}
		else
		{
			dbg << "Created a direct context.." << endl;
		}

		XFree(visInfo);

		if (!_context)
			localError("Unable to create GL context.");

		if (!glXMakeContextCurrent(_display, _pBuffer, _pBuffer, _context))
			localError("Unable to make context active.");

		// Should be able to use openGL here..

		GLenum glewErr = glewInit();
		if (glewErr != GLEW_OK)
		{
			cerr << "GLEW ERROR: " << glewGetErrorString(glewErr) << endl;
		}

		int majorVersion, minorVersion;
		glGetIntegerv(GL_MAJOR_VERSION, &majorVersion);
		glGetIntegerv(GL_MINOR_VERSION, &minorVersion);

		dbg << "GL Version: " << majorVersion << "." << minorVersion << endl;

		checkGlError("After context creation..");

		// Yay
		_ready = true;
	}
Exemplo n.º 8
0
bool
GetMWMHints(Window w, MotifWmHints *mwmHints)
{
	int success;
	Atom actual_type;
	int actual_format;
	unsigned long nitems;
	unsigned long bytes_after;
	unsigned long *prop = NULL;

	/* Defaults for when not found */
	mwmHints->flags = 0;
	mwmHints->functions = 0;
	mwmHints->decorations = 0;
#ifdef FULL_MWM_DATA
	mwmHints->input_mode = 0;
	mwmHints->status = 0;
#endif

	success = XGetWindowProperty(
	                  dpy, w, XA__MOTIF_WM_HINTS,
	                  0, 5,           /* long_offset, long long_length, */
	                  False,          /* Bool delete, */
	                  AnyPropertyType,/* Atom req_type */
	                  &actual_type,   /* Atom *actual_type_return, */
	                  &actual_format, /* int *actual_format_return, */
	                  &nitems,        /* unsigned long *nitems_return,  */
	                  &bytes_after,   /* unsigned long * */
	                  (unsigned char **)&prop);       /* unsigned char ** */

	if(success == Success &&
	                actual_type == XA__MOTIF_WM_HINTS &&
	                actual_format == 32 &&
	                nitems >= 3) {
		mwmHints->flags = (int)prop[0];
		mwmHints->functions = (int)prop[1];
		mwmHints->decorations = (int)prop[2];
#ifdef FULL_MWM_DATA
		mwmHints->input_mode = (int)prop[3];
		mwmHints->status = (int)prop[4];
#endif

		if(mwmHints->flags & MWM_HINTS_FUNCTIONS) {
			if(mwmHints->functions & MWM_FUNC_ALL) {
				mwmHints->functions ^= ~0;
			}
		}
		if(mwmHints->flags & MWM_HINTS_DECORATIONS) {
			if(mwmHints->decorations & MWM_DECOR_ALL) {
				mwmHints->decorations ^= ~0;
			}
		}

		success = true;
	}
	else {
		success = false;
	}

	if(prop != NULL) {
		XFree(prop);
	}

	return success;
}
Exemplo n.º 9
0
void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_command)
{
	int i, tx, ty;
	XImage* image;
	RFX_MESSAGE* message;
	xfInfo* xfi = ((xfContext*) context)->xfi;
	RFX_CONTEXT* rfx_context = (RFX_CONTEXT*) xfi->rfx_context;
	NSC_CONTEXT* nsc_context = (NSC_CONTEXT*) xfi->nsc_context;

	if (surface_bits_command->codecID == CODEC_ID_REMOTEFX)
	{
		message = rfx_process_message(rfx_context,
				surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);

		XSetFunction(xfi->display, xfi->gc, GXcopy);
		XSetFillStyle(xfi->display, xfi->gc, FillSolid);

		XSetClipRectangles(xfi->display, xfi->gc,
				surface_bits_command->destLeft, surface_bits_command->destTop,
				(XRectangle*) message->rects, message->num_rects, YXBanded);

		/* Draw the tiles to primary surface, each is 64x64. */
		for (i = 0; i < message->num_tiles; i++)
		{
			image = XCreateImage(xfi->display, xfi->visual, 24, ZPixmap, 0,
				(char*) message->tiles[i]->data, 64, 64, 32, 0);

			tx = message->tiles[i]->x + surface_bits_command->destLeft;
			ty = message->tiles[i]->y + surface_bits_command->destTop;

			XPutImage(xfi->display, xfi->primary, xfi->gc, image, 0, 0, tx, ty, 64, 64);
			XFree(image);
		}

		/* Copy the updated region from backstore to the window. */
		for (i = 0; i < message->num_rects; i++)
		{
			tx = message->rects[i].x + surface_bits_command->destLeft;
			ty = message->rects[i].y + surface_bits_command->destTop;

			if (xfi->remote_app != true)
			{
				XCopyArea(xfi->display, xfi->primary, xfi->drawable, xfi->gc,
						tx, ty, message->rects[i].width, message->rects[i].height, tx, ty);
			}

			gdi_InvalidateRegion(xfi->hdc, tx, ty, message->rects[i].width, message->rects[i].height);
		}

		XSetClipMask(xfi->display, xfi->gc, None);
		rfx_message_free(rfx_context, message);
	}
	else if (surface_bits_command->codecID == CODEC_ID_NSCODEC)
	{
		nsc_context->width = surface_bits_command->width;
		nsc_context->height = surface_bits_command->height;
		nsc_process_message(nsc_context, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
		XSetFunction(xfi->display, xfi->gc, GXcopy);
		XSetFillStyle(xfi->display, xfi->gc, FillSolid);

		xfi->bmp_codec_nsc = (uint8*) xrealloc(xfi->bmp_codec_nsc,
				surface_bits_command->width * surface_bits_command->height * 4);

		freerdp_image_flip(nsc_context->bmpdata, xfi->bmp_codec_nsc,
				surface_bits_command->width, surface_bits_command->height, 32);

		image = XCreateImage(xfi->display, xfi->visual, 24, ZPixmap, 0,
			(char*) xfi->bmp_codec_nsc, surface_bits_command->width, surface_bits_command->height, 32, 0);

		XPutImage(xfi->display, xfi->primary, xfi->gc, image, 0, 0,
				surface_bits_command->destLeft, surface_bits_command->destTop,
				surface_bits_command->width, surface_bits_command->height);

		if (xfi->remote_app != true)
		{
			XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc,
				surface_bits_command->destLeft, surface_bits_command->destTop,
				surface_bits_command->width, surface_bits_command->height,
				surface_bits_command->destLeft, surface_bits_command->destTop);
		}

		gdi_InvalidateRegion(xfi->hdc, surface_bits_command->destLeft, surface_bits_command->destTop,
				surface_bits_command->width, surface_bits_command->height);

		XSetClipMask(xfi->display, xfi->gc, None);
		nsc_context_destroy(nsc_context);
	}
	else if (surface_bits_command->codecID == CODEC_ID_NONE)
	{
		XSetFunction(xfi->display, xfi->gc, GXcopy);
		XSetFillStyle(xfi->display, xfi->gc, FillSolid);

		/* Validate that the data received is large enough */
		if( surface_bits_command->width * surface_bits_command->height * surface_bits_command->bpp / 8 <= surface_bits_command->bitmapDataLength )
		{
			xfi->bmp_codec_none = (uint8*) xrealloc(xfi->bmp_codec_none,
					surface_bits_command->width * surface_bits_command->height * 4);

			freerdp_image_flip(surface_bits_command->bitmapData, xfi->bmp_codec_none,
					surface_bits_command->width, surface_bits_command->height, 32);

			image = XCreateImage(xfi->display, xfi->visual, 24, ZPixmap, 0,
				(char*) xfi->bmp_codec_none, surface_bits_command->width, surface_bits_command->height, 32, 0);

			XPutImage(xfi->display, xfi->primary, xfi->gc, image, 0, 0,
					surface_bits_command->destLeft, surface_bits_command->destTop,
					surface_bits_command->width, surface_bits_command->height);

			if (xfi->remote_app != true)
			{
				XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc,
					surface_bits_command->destLeft, surface_bits_command->destTop,
					surface_bits_command->width, surface_bits_command->height,
					surface_bits_command->destLeft, surface_bits_command->destTop);
			}

			gdi_InvalidateRegion(xfi->hdc, surface_bits_command->destLeft, surface_bits_command->destTop,
					surface_bits_command->width, surface_bits_command->height);

			XSetClipMask(xfi->display, xfi->gc, None);
		} else {
			printf("Invalid bitmap size - data is %d bytes for %dx%d\n update", surface_bits_command->bitmapDataLength, surface_bits_command->width, surface_bits_command->height);
		}
	}
	else
	{
		printf("Unsupported codecID %d\n", surface_bits_command->codecID);
	}
}
Exemplo n.º 10
0
int main(int argc, char **argv) {
    EGLDisplay	sEGLDisplay;
    EGLContext	sEGLContext;
    EGLSurface	sEGLSurface;

    /* EGL Configuration */

    EGLint aEGLAttributes[] = {
        EGL_RED_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_BLUE_SIZE, 8,
        EGL_DEPTH_SIZE, 16,
        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
        EGL_NONE
    };

    EGLint aEGLContextAttributes[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };

    EGLConfig	aEGLConfigs[1];
    EGLint		cEGLConfigs;

#ifdef _WIN32
    MSG sMessage;
#else
    XSetWindowAttributes win_attrs;
    int attrs[64], idx = 0, num_config = 0;
    int major, minor;
    Colormap colormap;
    XVisualInfo *pVisual;
    XEvent e;
#endif

    GLint iLocPosition = 0;

    GLint iLocColour, iLocTexCoord, iLocNormal, iLocMVP;
    GLint iLocXangle, iLocYangle, iLocZangle;
    GLint iLocAspect, iLocLightPos, iLocSampler, iLocSampler2;

    GLuint uiProgram, uiFragShader, uiVertShader;

    GLenum myTex, myTex2;

    int bDone = 0;

    const unsigned int uiWidth  = 640;
    const unsigned int uiHeight = 480;

    int iXangle = 0, iYangle = 0, iZangle = 0;

    float aTBNmatrix1[9], aTBNmatrix2[9];

    float aLightPos[] = { 0.0f, 0.0f, -1.0f }; // Light is nearest camera.

    unsigned char *myPixels = calloc(1, 128*128*4); // Holds texture data.
    unsigned char *myPixels2 = calloc(1, 128*128*4); // Holds texture data.

    float aRotate[16], aModelView[16], aPerspective[16], aMVP[16];

    int i;

    /* EGL Init */

#ifdef _WIN32
    hDisplay = EGL_DEFAULT_DISPLAY;
#else
    hDisplay = XOpenDisplay(NULL);

    if (!hDisplay) {
        printf("Could not open display\n");
        exit(-1);
    }
#endif

    sEGLDisplay = EGL_CHECK(eglGetDisplay(hDisplay));

    EGL_CHECK(eglInitialize(sEGLDisplay, NULL, NULL));
    EGL_CHECK(eglChooseConfig(sEGLDisplay, aEGLAttributes, aEGLConfigs, 1, &cEGLConfigs));

    if (cEGLConfigs == 0) {
        printf("No EGL configurations were returned.\n");
        exit(-1);
    }

#ifdef _WIN32
    hWindow = create_window(uiWidth, uiHeight);
#else
    hWindow = create_window("OpenGL ES 2.0 Example on a Linux Desktop", uiWidth,
        uiHeight, hDisplay, sEGLDisplay, aEGLConfigs[0], &colormap, &pVisual);
#endif

    sEGLSurface = EGL_CHECK(eglCreateWindowSurface(sEGLDisplay, aEGLConfigs[0], (EGLNativeWindowType)hWindow, NULL));

    if (sEGLSurface == EGL_NO_SURFACE) {
        printf("Failed to create EGL surface.\n");
        exit(-1);
    }

    sEGLContext = EGL_CHECK(eglCreateContext(sEGLDisplay, aEGLConfigs[0], EGL_NO_CONTEXT, aEGLContextAttributes));

    if (sEGLContext == EGL_NO_CONTEXT) {
        printf("Failed to create EGL context.\n");
        exit(-1);
    }

    EGL_CHECK(eglMakeCurrent(sEGLDisplay, sEGLSurface, sEGLSurface, sEGLContext));

    /* Shader Initialisation */
    process_shader(&uiVertShader, "shader.vert", GL_VERTEX_SHADER);
    process_shader(&uiFragShader, "shader.frag", GL_FRAGMENT_SHADER);

    /* Create uiProgram (ready to attach shaders) */
    uiProgram = GL_CHECK(glCreateProgram());

    /* Attach shaders and link uiProgram */
    GL_CHECK(glAttachShader(uiProgram, uiVertShader));
    GL_CHECK(glAttachShader(uiProgram, uiFragShader));
    GL_CHECK(glLinkProgram(uiProgram));

    /* Get attribute locations of non-fixed attributes like colour and texture coordinates. */
    iLocPosition = GL_CHECK(glGetAttribLocation(uiProgram, "av4position"));
    iLocColour = GL_CHECK(glGetAttribLocation(uiProgram, "av3colour"));

#ifdef DEBUG
    printf("iLocPosition = %i\n", iLocPosition);
    printf("iLocColour   = %i\n", iLocColour);
#endif

    /* Get uniform locations */
    iLocMVP = GL_CHECK(glGetUniformLocation(uiProgram, "mvp"));

#ifdef DEBUG
    printf("iLocMVP      = %i\n", iLocMVP);
#endif

    GL_CHECK(glUseProgram(uiProgram));

    /* Enable attributes for position, colour and texture coordinates etc. */
    GL_CHECK(glEnableVertexAttribArray(iLocPosition));
    GL_CHECK(glEnableVertexAttribArray(iLocColour));

    /* Populate attributes for position, colour and texture coordinates etc. */
    GL_CHECK(glVertexAttribPointer(iLocPosition, 3, GL_FLOAT, GL_FALSE, 0, aVertices));
    GL_CHECK(glVertexAttribPointer(iLocColour, 3, GL_FLOAT, GL_FALSE, 0, aColours));

    GL_CHECK(glEnable(GL_CULL_FACE));
    GL_CHECK(glEnable(GL_DEPTH_TEST));

#ifndef _WIN32
    XSelectInput(hDisplay, hWindow, KeyPressMask | ExposureMask | EnterWindowMask
        | LeaveWindowMask | PointerMotionMask | VisibilityChangeMask | ButtonPressMask
        | ButtonReleaseMask | StructureNotifyMask);
#endif

    /* Enter event loop */
    while (!bDone) {
#ifdef _WIN32
        if(PeekMessage(&sMessage, NULL, 0, 0, PM_REMOVE)) {
            if(sMessage.message == WM_QUIT) {
                bDone = 1;
            } else {
                TranslateMessage(&sMessage);
                DispatchMessage(&sMessage);
            }
        }
#else
        while (XPending(hDisplay) > 0) {
            XNextEvent(hDisplay, &e);

            if (e.type == ButtonPress) {
                bDone = 1;
            }
        }
#endif

        /* 
        * Do some rotation with Euler angles. It is not a fixed axis as
        * quaterions would be, but the effect is cool. 
        */
        rotate_matrix(iXangle, 1.0, 0.0, 0.0, aModelView);
        rotate_matrix(iYangle, 0.0, 1.0, 0.0, aRotate);

        multiply_matrix(aRotate, aModelView, aModelView);

        rotate_matrix(iZangle, 0.0, 1.0, 0.0, aRotate);

        multiply_matrix(aRotate, aModelView, aModelView);

        /* Pull the camera back from the cube */
        aModelView[14] -= 2.5;

        perspective_matrix(45.0, (double)uiWidth/(double)uiHeight, 0.01, 100.0, aPerspective);
        multiply_matrix(aPerspective, aModelView, aMVP);

        GL_CHECK(glUniformMatrix4fv(iLocMVP, 1, GL_FALSE, aMVP));

        iXangle += 3;
        iYangle += 2;
        iZangle += 1;

        if(iXangle >= 360) iXangle -= 360;
        if(iXangle < 0) iXangle += 360;
        if(iYangle >= 360) iYangle -= 360;
        if(iYangle < 0) iYangle += 360;
        if(iZangle >= 360) iZangle -= 360;
        if(iZangle < 0) iZangle += 360;

        GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT));
        GL_CHECK(glDrawArrays(GL_TRIANGLES, 0, 36));

        if (!eglSwapBuffers(sEGLDisplay, sEGLSurface)) {
            printf("Failed to swap buffers.\n");
        }

#ifdef _WIN32
        Sleep(20);
#else
        usleep(20000);
#endif
    }

    /* Cleanup shaders */
    GL_CHECK(glUseProgram(0));
    GL_CHECK(glDeleteShader(uiVertShader));
    GL_CHECK(glDeleteShader(uiFragShader));
    GL_CHECK(glDeleteProgram(uiProgram));

    /* EGL clean up */
    EGL_CHECK(eglMakeCurrent(sEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    EGL_CHECK(eglDestroySurface(sEGLDisplay, sEGLSurface));
    EGL_CHECK(eglDestroyContext(sEGLDisplay, sEGLContext));
    EGL_CHECK(eglTerminate(sEGLDisplay));

#ifndef _WIN32
    /* X windows clean up */
    XDestroyWindow(hDisplay, hWindow);
    XFreeColormap(hDisplay, colormap);
    XFree(pVisual);
    XCloseDisplay(hDisplay);
#endif

    return 0;
}
Exemplo n.º 11
0
struct platform *gr3_platform_initGL_dynamic_(void (*log_callback)(const char *),
                                              void (*appendtorenderpathstring_callback)(const char *))
{

  int major = 0, minor = 0;
  int fbcount = 0;
  GLXFBConfig *fbc;
  GLXFBConfig fbconfig = (GLXFBConfig)NULL;
  pbuffer = (GLXPbuffer)NULL;

  gr3_log_ = log_callback;
  gr3_appendtorenderpathstring_ = appendtorenderpathstring_callback;
  gr3_log_("gr3_platform_initGL_dynamic_");
  gr3_platform_.getProcAddress = (void (*(*)(const char *))()) & glXGetProcAddress;

  display = XOpenDisplay(0);
  if (!display)
    {
      gr3_log_("Not connected to an X server!");
      return NULL;
    }
  if (!glXQueryExtension(display, NULL, NULL))
    {
      gr3_log_("GLX not supported!");
      return NULL;
    }

  context = glXGetCurrentContext();
  if (context != NULL)
    {
      gr3_appendtorenderpathstring_("GLX (existing context)");
    }
  else
    {
      /* call glXQueryVersion twice to prevent bugs in virtualbox */
      if (!glXQueryVersion(display, &major, &minor) && !glXQueryVersion(display, &major, &minor))
        {
          return NULL;
        }
      if (major > 1 || minor >= 4)
        {
          int (*x_error_handler)() = _gr3_ignore_x_errors;
          int i;
          int fb_attribs[] = {GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT, GLX_RENDER_TYPE, GLX_RGBA_BIT, None};
          int pbuffer_attribs[] = {GLX_PBUFFER_WIDTH, 1, GLX_PBUFFER_HEIGHT, 1, None};
          gr3_log_("(Pbuffer)");

          fbc = glXChooseFBConfig(display, DefaultScreen(display), fb_attribs, &fbcount);
          if (fbcount == 0)
            {
              gr3_log_("failed to find a valid a GLX FBConfig for a RGBA PBuffer");
              XFree(fbc);
              XCloseDisplay(display);
              return NULL;
            }
          /* Failed creation of a pbuffer may cause X errors, which we need to ignore */
          XSynchronize(display, 1);
          x_error_handler = XSetErrorHandler(_gr3_ignore_x_errors);
          for (i = 0; i < fbcount && !pbuffer; i++)
            {
              fbconfig = fbc[i];
              pbuffer = glXCreatePbuffer(display, fbconfig, pbuffer_attribs);
            }
          XSetErrorHandler(x_error_handler);
          XSynchronize(display, 0);
          XFree(fbc);
          if (!pbuffer)
            {
              gr3_log_("failed to create a RGBA PBuffer");
              XCloseDisplay(display);
              return NULL;
            }

          context = glXCreateNewContext(display, fbconfig, GLX_RGBA_TYPE, None, True);
          glXMakeContextCurrent(display, pbuffer, pbuffer, context);
          gr3_platform_.terminateGL = &gr3_terminateGL_GLX_Pbuffer_;
          gr3_appendtorenderpathstring_("GLX (Pbuffer)");
        }
      else
        {
          XVisualInfo *visual;
          int fb_attribs[] = {GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, GLX_RENDER_TYPE, GLX_RGBA_BIT, None};
          gr3_log_("(XPixmap)");
          fbc = glXChooseFBConfig(display, DefaultScreen(display), fb_attribs, &fbcount);
          if (fbcount == 0)
            {
              gr3_log_("failed to find a valid a GLX FBConfig for a RGBA Pixmap");
              XFree(fbc);
              XCloseDisplay(display);
              return NULL;
            }
          fbconfig = fbc[0];
          XFree(fbc);

          context = glXCreateNewContext(display, fbconfig, GLX_RGBA_TYPE, None, True);
          visual = glXGetVisualFromFBConfig(display, fbconfig);
          pixmap = XCreatePixmap(display, XRootWindow(display, DefaultScreen(display)), 1, 1, visual->depth);

          if (glXMakeContextCurrent(display, pixmap, pixmap, context))
            {
              gr3_platform_.terminateGL = &gr3_terminateGL_GLX_Pixmap_;
              gr3_appendtorenderpathstring_("GLX (XPixmap)");
            }
          else
            {
              gr3_log_("failed to make GLX OpenGL Context current with a Pixmap");
              glXDestroyContext(display, context);
              XFreePixmap(display, pixmap);
              XCloseDisplay(display);
              return NULL;
            }
        }
    }
  return &gr3_platform_;
}
Exemplo n.º 12
0
	//-------------------------------------------------------------------------------------------------//
	GLXGLSupport::GLXGLSupport() : mGLDisplay(0), mXDisplay(0)
	{
		// A connection that might be shared with the application for GL rendering:
		mGLDisplay = getGLDisplay();

		// A connection that is NOT shared to enable independent event processing:
		mXDisplay  = getXDisplay();

		int dummy;

		if (XQueryExtension(mXDisplay, "RANDR", &dummy, &dummy, &dummy))
		{
			XRRScreenConfiguration *screenConfig;

			screenConfig = XRRGetScreenInfo(mXDisplay, DefaultRootWindow(mXDisplay));

			if (screenConfig)
			{
				XRRScreenSize *screenSizes;
				int nSizes = 0;
				Rotation currentRotation;
				int currentSizeID = XRRConfigCurrentConfiguration(screenConfig, &currentRotation);

				screenSizes = XRRConfigSizes(screenConfig, &nSizes);

				mCurrentMode.first.first = screenSizes[currentSizeID].width;
				mCurrentMode.first.second = screenSizes[currentSizeID].height;
				mCurrentMode.second = XRRConfigCurrentRate(screenConfig);

				mOriginalMode = mCurrentMode;

				for(int sizeID = 0; sizeID < nSizes; sizeID++)
				{
					short *rates;
					int nRates = 0;

					rates = XRRConfigRates(screenConfig, sizeID, &nRates);

					for (int rate = 0; rate < nRates; rate++)
					{
						VideoMode mode;

						mode.first.first = screenSizes[sizeID].width;
						mode.first.second = screenSizes[sizeID].height;
						mode.second = rates[rate];

						mVideoModes.push_back(mode);
					}
				}
				XRRFreeScreenConfigInfo(screenConfig);
			}
		}
		else
		{
			mCurrentMode.first.first = DisplayWidth(mXDisplay, DefaultScreen(mXDisplay));
			mCurrentMode.first.second = DisplayHeight(mXDisplay, DefaultScreen(mXDisplay));
			mCurrentMode.second = 0;

			mOriginalMode = mCurrentMode;

			mVideoModes.push_back(mCurrentMode);
		}

		GLXFBConfig *fbConfigs;
		int config, nConfigs = 0;

		fbConfigs = chooseFBConfig(NULL, &nConfigs);

		for (config = 0; config < nConfigs; config++)
		{
			int caveat, samples;

			getFBConfigAttrib (fbConfigs[config], GLX_CONFIG_CAVEAT, &caveat);

			if (caveat != GLX_SLOW_CONFIG)
			{
				getFBConfigAttrib (fbConfigs[config], GLX_SAMPLES, &samples);
				mSampleLevels.push_back(StringConverter::toString(samples));
			}
		}

		XFree (fbConfigs);

		remove_duplicates(mSampleLevels);
	}
Exemplo n.º 13
0
void sdlvideo_monitor_refresh(sdl_monitor_info *monitor)
{
	#if (SDLMAME_SDL2)
	SDL_DisplayMode dmode;

	SDL_GetDesktopDisplayMode(monitor->handle, &dmode);
	monitor->monitor_width = dmode.w;
	monitor->monitor_height = dmode.h;
	monitor->center_width = dmode.w;
	monitor->center_height = dmode.h;
	#else
	#if defined(SDLMAME_WIN32)  // Win32 version
	MONITORINFOEX info;
	info.cbSize = sizeof(info);
	GetMonitorInfo((HMONITOR)monitor->handle, (LPMONITORINFO)&info);
	monitor->center_width = monitor->monitor_width = info.rcMonitor.right - info.rcMonitor.left;
	monitor->center_height = monitor->monitor_height = info.rcMonitor.bottom - info.rcMonitor.top;
	char *temp = utf8_from_wstring(info.szDevice);
	strcpy(monitor->monitor_device, temp);
	osd_free(temp);
	#elif defined(SDLMAME_MACOSX)   // Mac OS X Core Imaging version
	CGDirectDisplayID primary;
	CGRect dbounds;

	// get the main display
	primary = CGMainDisplayID();
	dbounds = CGDisplayBounds(primary);

	monitor->center_width = monitor->monitor_width = dbounds.size.width - dbounds.origin.x;
	monitor->center_height = monitor->monitor_height = dbounds.size.height - dbounds.origin.y;
	strcpy(monitor->monitor_device, "Mac OS X display");
	#elif defined(SDLMAME_X11) || defined(SDLMAME_NO_X11)       // X11 version
	{
		#if defined(SDLMAME_X11)
		// X11 version
		int screen;
		SDL_SysWMinfo info;
		SDL_VERSION(&info.version);

		if ( SDL_GetWMInfo(&info) && (info.subsystem == SDL_SYSWM_X11) )
		{
			screen = DefaultScreen(info.info.x11.display);
			SDL_VideoDriverName(monitor->monitor_device, sizeof(monitor->monitor_device)-1);
			monitor->monitor_width = DisplayWidth(info.info.x11.display, screen);
			monitor->monitor_height = DisplayHeight(info.info.x11.display, screen);

			if ((XineramaIsActive(info.info.x11.display)) && video_config.restrictonemonitor)
			{
				XineramaScreenInfo *xineinfo;
				int numscreens;

					xineinfo = XineramaQueryScreens(info.info.x11.display, &numscreens);

				monitor->center_width = xineinfo[0].width;
				monitor->center_height = xineinfo[0].height;

				XFree(xineinfo);
			}
			else
			{
				monitor->center_width = monitor->monitor_width;
				monitor->center_height = monitor->monitor_height;
			}
		}
		else
		#endif // defined(SDLMAME_X11)
		{
			static int first_call=0;
			static int cw = 0, ch = 0;

			SDL_VideoDriverName(monitor->monitor_device, sizeof(monitor->monitor_device)-1);
			if (first_call==0)
			{
				char *dimstr = osd_getenv(SDLENV_DESKTOPDIM);
				const SDL_VideoInfo *sdl_vi;

				sdl_vi = SDL_GetVideoInfo();
				#if (SDL_VERSION_ATLEAST(1,2,10))
				cw = sdl_vi->current_w;
				ch = sdl_vi->current_h;
				#endif
				first_call=1;
				if ((cw==0) || (ch==0))
				{
					if (dimstr != NULL)
					{
						sscanf(dimstr, "%dx%d", &cw, &ch);
					}
					if ((cw==0) || (ch==0))
					{
						mame_printf_warning("WARNING: SDL_GetVideoInfo() for driver <%s> is broken.\n", monitor->monitor_device);
						mame_printf_warning("         You should set SDLMAME_DESKTOPDIM to your desktop size.\n");
						mame_printf_warning("            e.g. export SDLMAME_DESKTOPDIM=800x600\n");
						mame_printf_warning("         Assuming 1024x768 now!\n");
						cw=1024;
						ch=768;
					}
				}
			}
			monitor->monitor_width = cw;
			monitor->monitor_height = ch;
			monitor->center_width = cw;
			monitor->center_height = ch;
		}
	}
	#elif defined(SDLMAME_OS2)      // OS2 version
	monitor->center_width = monitor->monitor_width = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
	monitor->center_height = monitor->monitor_height = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );
	strcpy(monitor->monitor_device, "OS/2 display");
	#else
	#error Unknown SDLMAME_xx OS type!
	#endif

	{
		static int info_shown=0;
		if (!info_shown)
		{
			mame_printf_verbose("SDL Device Driver     : %s\n", monitor->monitor_device);
			mame_printf_verbose("SDL Monitor Dimensions: %d x %d\n", monitor->monitor_width, monitor->monitor_height);
			info_shown = 1;
		}
	}
	#endif //  (SDLMAME_SDL2)
}
Exemplo n.º 14
0
	BD_UINT32 LinuxWindow::Create( const BD_UINT32 p_Width,
		const BD_UINT32 p_Height, const BD_BOOL p_Fullscreen )
	{
		m_pDisplay = XOpenDisplay( 0 );

		if( !m_pDisplay )
		{
			bdTrace( BD_NULL, "[BD::LinuxWindow::Create] <ERROR> "
				"Failed to open X display\n" );

			return BD_ERROR;
		}

		m_Fullscreen = p_Fullscreen;

		// HARDCODED!
		BD_SINT32 GLXAttribs[ ] =
		{
			GLX_X_RENDERABLE,	True,
			GLX_DRAWABLE_TYPE,	GLX_WINDOW_BIT,
			GLX_RENDER_TYPE,	GLX_RGBA_BIT,
			GLX_X_VISUAL_TYPE,	GLX_TRUE_COLOR,
			GLX_RED_SIZE,		8,
			GLX_GREEN_SIZE,		8,
			GLX_BLUE_SIZE,		8,
			GLX_ALPHA_SIZE,		8,
			GLX_DEPTH_SIZE,		24,
			GLX_STENCIL_SIZE,	8,
			GLX_DOUBLEBUFFER,	True,
			None
		};
		// !HARDCODED

		// For now, we will only care about GLX 1.3
		BD_SINT32 Major = 0, Minor = 0;

		if( !glXQueryVersion( m_pDisplay, &Major, &Minor ) ||
			( ( Major == 1 ) && ( Minor < 3 ) ) || ( Major < 1 ) )
		{
			bdTrace( BD_NULL, "[BD::LinuxWindow::Create] <ERROR> "
				"GLX Version not 1.3 or greater\n" );
			return BD_ERROR;
		}

		bdTrace( BD_NULL, "[BD::LinuxWindow::Create] <INFO> "
			"Attempting to retrieve framebuffer configurations\n" );

		BD_SINT32 FBCount = 0;
		GLXFBConfig *pFBC = glXChooseFBConfig( m_pDisplay,
			DefaultScreen( m_pDisplay ), GLXAttribs, &FBCount );

		if( !pFBC )
		{
			bdTrace( BD_NULL, "[BD::LinuxWindow::Create] <ERROR> "
				"Failed to create a GLXFBConfig\n" );
			return BD_ERROR;
		}

		bdTrace( BD_NULL, "[BD::LinuxWindow::Create] <INFO> "
			"Found %d matching framebuffer configurations\n", FBCount );

		GLXFBConfig FBC = pFBC[ 0 ];

		m_pXVI = glXGetVisualFromFBConfig( m_pDisplay, FBC );

		XFree( pFBC );

		bdTrace( BD_NULL, "[BD::LinuxWindow::Create] <INFO> "
			"Visual ID in use: 0x%08X\n", m_pXVI->visualid );

		XSetWindowAttributes WinAttribs;
		Colormap ColourMap = XCreateColormap( m_pDisplay,
			RootWindow( m_pDisplay, m_pXVI->screen ), m_pXVI->visual,
			AllocNone );

		WinAttribs.colormap = ColourMap;
		WinAttribs.background_pixmap = None;
		WinAttribs.border_pixel = 0;
		WinAttribs.event_mask = StructureNotifyMask | ExposureMask |
			KeyPressMask | KeyReleaseMask |
			ButtonPressMask | ButtonReleaseMask | PointerMotionMask;

		Screen *pScreen = DefaultScreenOfDisplay( m_pDisplay );

		if( m_Fullscreen == BD_TRUE )
		{
			m_Width = WidthOfScreen( pScreen );
			m_Height = HeightOfScreen( pScreen );
		}
		else
		{
			m_Width = p_Width;
			m_Height = p_Height;
		}

		BD::GLWSExtBind( m_pDisplay, m_pXVI->screen );

		m_Window = XCreateWindow( m_pDisplay,
			RootWindow( m_pDisplay, m_pXVI->screen ),
			0, 0, m_Width, m_Height, 0, m_pXVI->depth, InputOutput,
			m_pXVI->visual, CWEventMask | CWColormap | CWBorderPixel,
			&WinAttribs );

		if( !m_Window )
		{
			bdTrace( BD_NULL, "[BD::LinuxWindow::CreateWindow] <INFO> "
				"Failed to create window\n" );
			return BD_ERROR;
		}

		bdTrace( BD_NULL, "[BD::LinuxWindow::CreateWindow] <INFO> "
			"m_Window: 0x%08X | Width: %d | Height %d | Fullscreen: %s\n",
			m_Window, m_Width, m_Height, ( m_Fullscreen ? "True" : "False" ) );

		XMapWindow( m_pDisplay, m_Window );
		XMapRaised( m_pDisplay, m_Window );

		XStoreName( m_pDisplay, m_Window, "BrainDead" );
		XMoveWindow( m_pDisplay, m_Window, 0, 0 );
		XRaiseWindow( m_pDisplay, m_Window );

		XSync( m_pDisplay, False );

		// Install an X error handler so the application won't exit if
		// GL 3.0+ context allocation fails
		g_sContextError = BD_FALSE;
		int ( *pOldHandler )( Display *, XErrorEvent * ) =
			XSetErrorHandler( &ContextErrorHandler );

		if( !bglwsCreateContextAttribsARB )
		{
			// Create a GLX 1.3 context for GL <2.1
			bdTrace( BD_NULL, "[BD::LinuxWindow::Create] <INFO> "
				"Creating a GLX 1.3 context\n" );
			m_GLXContext = glXCreateNewContext( m_pDisplay, FBC, GLX_RGBA_TYPE,
				0, True );
		}
		else
		{
			BD_SINT32 GLVersions [ ] =
			{
				4, 3,
				4, 2,
				4, 1,
				4, 0,
				3, 3,
				3, 2,
				3, 1,
				3, 0,
				2, 1,
				2, 0,
				1, 5,
				1, 4,
				1, 3, 
				1, 2,
				1, 1,
				1, 0
			};

			int ContextAttribs [ ] =
			{
				GLX_CONTEXT_MAJOR_VERSION_ARB,	0,
				GLX_CONTEXT_MINOR_VERSION_ARB,	0,
#ifdef BUILD_DEBUG
				GLX_CONTEXT_FLAGS_ARB,	GLX_CONTEXT_DEBUG_BIT_ARB,
#endif
				// Add forward-compatible and debug if debug
				None
			};

			for( BD_MEMSIZE i = 0;
				i < ( sizeof( GLVersions ) / sizeof( BD_SINT32 ) / 2 ); ++i )
			{
				bdTrace( BD_NULL, "[BD::LinuxWindow::Create] <INFO> "
					"Attempting to create a GLX context for OpenGL "
					"%ld.%ld... ",
					GLVersions[ i*2 ], GLVersions[ i*2+1 ] );	
				ContextAttribs[ 1 ] = GLVersions[ i*2 ];
				ContextAttribs[ 3 ] = GLVersions[ i*2+1 ];

				m_GLXContext = bglwsCreateContextAttribsARB( m_pDisplay, FBC,
					0, True, ContextAttribs );

				XSync( m_pDisplay, False );

				if( !g_sContextError && m_GLXContext )
				{
					bdTrace( BD_NULL, "[ OK ]\n" );
					break;
				}
				g_sContextError = BD_FALSE;
				bdTrace( BD_NULL, "\n" );
			}
		}

		// Sync to make sure any errors are processed
		XSync( m_pDisplay, False );

		// Restore the  original error handler
		XSetErrorHandler( pOldHandler );

		if( g_sContextError || !m_GLXContext )
		{
			bdTrace( BD_NULL, "[BD::LinuxWindow::Create] <ERROR> "
				"Failed to create an OpenGL context\n" );
			return BD_ERROR;
		}

		if( !glXIsDirect( m_pDisplay, m_GLXContext ) )
		{
			bdTrace( BD_NULL, "[BD::LinuxWindow::Create] <WARN> "
				"Indirect GLX rendering context\n" );
		}
		else
		{
			bdTrace( BD_NULL, "[BD::LinuxWindow::Create] <INFO> "
				"Direct GLX rendering context\n" );
		}

		glXMakeCurrent( m_pDisplay, m_Window, m_GLXContext );
		
		// Get the version information to initialise the GL Extensions
		GLint GLMajor = 0, GLMinor = 0;

		// Attempt to get the major and minor using the GL 3.0+ method
		bglGetIntegerv( GL_MAJOR_VERSION, &GLMajor );
		bglGetIntegerv( GL_MINOR_VERSION, &GLMinor );

		// The GL_*_VERSION parameters are not recognised
		GLenum GLErr = bglGetError( );
		if( GLErr == GL_INVALID_ENUM )
		{
			// Resort to using the <GL 3.0 method
			const char *pGLVersion = ( const char * )glGetString( GL_VERSION );

			// The first number up to the first period /should/ be the major
			BD_MEMSIZE Separator = 0;
			BD_MEMSIZE StrCount = 0;
			BD_MEMSIZE StrLoc = 0;

			GLMajor = 0;
			GLMinor = 0;

			char *pNum = BD_NULL;
			for( BD_MEMSIZE i = 0; i < strlen( pGLVersion ); ++i )
			{
				char c = pGLVersion[ i ];
				if( c == '.' )
				{
					pNum = new char[ StrCount+1 ];

					strncpy( pNum, pGLVersion+StrLoc, StrCount );
					pNum[ StrCount ] = '\0';

					StrLoc = StrCount+1;
					StrCount = 0;
					// Skip the '.'
					++i;

					if( GLMajor != 0 )
					{
						GLMinor = atoi( pNum );
						break;
					}	
					if( GLMajor == 0 )
					{
						GLMajor = atoi( pNum );
					}
				}
				StrCount++;
			}

			delete [ ] pNum;
		}

		if( BD::GLExtBind( GLMajor, GLMinor ) != BD_OK )
		{
			bdTrace( BD_NULL, "[BD::LinuxRenderer::Create] <ERROR> "
				"Failed to bind OpenGL %d.%d extensions\n", GLMajor, GLMinor );	
			bdTrace( BD_NULL, "[ FAIL ]\n" );
			return BD_ERROR;
		}

		bdTrace( BD_NULL, "[BD::LinuxRenderer::Create] <INFO> "
			"Bound OpenGL %d.%d extensions\n", GLMajor, GLMinor );

		bglViewport( 0, 0, m_Width, m_Height );

		return BD_OK;
	}
Exemplo n.º 15
0
 ~EglVisual() {
     XFree(visinfo);
 }
Exemplo n.º 16
0
static int _gfx_x11_init_monitors(

		int  major,
		int  minor)
{
	/* Iterate over all screens */
	Screen* def = XDefaultScreenOfDisplay(_gfx_x11.display);
	unsigned int count = XScreenCount(_gfx_x11.display);

	while(count--)
	{
		/* Get screen resources */
		Screen* scr =
			XScreenOfDisplay(_gfx_x11.display, count);
		Window root =
			XRootWindowOfScreen(scr);
		XRRScreenResources* res =
			XRRGetScreenResources(_gfx_x11.display, root);
		RROutput prim =
			res->outputs[0];

		/* Get primary if RandR 1.3 is supported */
		if(major > 1 || (major == 1 && minor > 2))
			prim = XRRGetOutputPrimary(_gfx_x11.display, root);

		/* Insert the screen's display modes */
		size_t first = _gfx_x11_init_modes(scr, res);

		/* Iterate through outputs */
		unsigned int i;
		for(i = 0; i < res->noutput; ++i)
		{
			/* Validate output */
			XRROutputInfo* out =
				XRRGetOutputInfo(_gfx_x11.display, res, res->outputs[i]);

			if(out->connection != RR_Connected)
			{
				XRRFreeOutputInfo(out);
				continue;
			}

			/* Create new monitor */
			XRRCrtcInfo* crtc =
				XRRGetCrtcInfo(_gfx_x11.display, res, out->crtc);
			int rot =
				crtc->rotation & (RR_Rotate_90 | RR_Rotate_270);

			GFX_X11_Monitor mon =
			{
				.screen   = scr,
				.crtc     = out->crtc,
				.mode     = crtc->mode,
				.numModes = 0,
				.modes    = malloc(sizeof(size_t) * out->nmode),
				.x        = crtc->x,
				.y        = crtc->y,
				.width    = rot ? crtc->height : crtc->width,
				.height   = rot ? crtc->width : crtc->height
			};

			/* Retrieve output modes */
			unsigned int j;
			if(mon.modes) for(j = 0; j < out->nmode; ++j)
			{
				GFX_X11_Mode* mode;
				for(
					mode = gfx_vector_at(&_gfx_x11.modes, first);
					mode != _gfx_x11.modes.end;
					mode = gfx_vector_next(&_gfx_x11.modes, mode))
				{
					/* Also check if resolution isn't too big */
					if(
						mode->id == out->modes[j] &&
						mode->mode.width <= crtc->width &&
						mode->mode.height <= crtc->height)
					{
						mon.modes[mon.numModes++] = gfx_vector_get_index(
							&_gfx_x11.modes,
							mode
						);
						break;
					}
				}
			}

			/* Insert at beginning if primary */
			GFXVectorIterator monPos =
				scr == def && res->outputs[i] == prim ?
				_gfx_x11.monitors.begin : _gfx_x11.monitors.end;

			monPos = gfx_vector_insert(&_gfx_x11.monitors, &mon, monPos);
			if(monPos == _gfx_x11.monitors.end) free(mon.modes);

			XRRFreeCrtcInfo(crtc);
			XRRFreeOutputInfo(out);
		}

		XRRFreeScreenResources(res);
	}

	/* Need at least one monitor */
	return _gfx_x11.monitors.begin != _gfx_x11.monitors.end;
}

/******************************************************/
static GFXKey _gfx_x11_get_key(

		KeySym symbol)
{
	/* Unicode numbers */
	if(symbol >= XK_0 && symbol <= XK_9)
		return (GFXKey)(symbol - XK_0 + GFX_KEY_0);

	/* Keypad numbers */
	if(symbol >= XK_KP_0 && symbol <= XK_KP_9)
		return (GFXKey)(symbol - XK_KP_0 + GFX_KEY_KP_0);

	/* Unicode capitals */
	if(symbol >= XK_A && symbol <= XK_Z)
		return (GFXKey)(symbol - XK_A + GFX_KEY_A);

	/* Unicode lowercase */
	if(symbol >= XK_a && symbol <= XK_z)
		return (GFXKey)(symbol - XK_a + GFX_KEY_A);

	/* Function keys */
	if(symbol >= XK_F1 && symbol <= XK_F24)
		return (GFXKey)(symbol - XK_F1 + GFX_KEY_F1);

	/* Non-unicode */
	switch(symbol)
	{
		case XK_VoidSymbol   : return GFX_KEY_UNKNOWN;

		case XK_BackSpace    : return GFX_KEY_BACKSPACE;
		case XK_Tab          : return GFX_KEY_TAB;
		case XK_KP_Tab       : return GFX_KEY_TAB;
		case XK_Clear        : return GFX_KEY_CLEAR;
		case XK_Return       : return GFX_KEY_RETURN;
		case XK_Pause        : return GFX_KEY_PAUSE;
		case XK_Scroll_Lock  : return GFX_KEY_SCROLL_LOCK;
		case XK_Escape       : return GFX_KEY_ESCAPE;
		case XK_Delete       : return GFX_KEY_DELETE;
		case XK_KP_Delete    : return GFX_KEY_DELETE;

		case XK_Home         : return GFX_KEY_HOME;
		case XK_KP_Home      : return GFX_KEY_HOME;
		case XK_Left         : return GFX_KEY_LEFT;
		case XK_KP_Left      : return GFX_KEY_LEFT;
		case XK_Up           : return GFX_KEY_UP;
		case XK_KP_Up        : return GFX_KEY_UP;
		case XK_Right        : return GFX_KEY_RIGHT;
		case XK_KP_Right     : return GFX_KEY_RIGHT;
		case XK_Down         : return GFX_KEY_DOWN;
		case XK_KP_Down      : return GFX_KEY_DOWN;
		case XK_Page_Down    : return GFX_KEY_PAGE_DOWN;
		case XK_KP_Page_Down : return GFX_KEY_PAGE_DOWN;
		case XK_Page_Up      : return GFX_KEY_PAGE_UP;
		case XK_KP_Page_Up   : return GFX_KEY_PAGE_UP;
		case XK_End          : return GFX_KEY_END;
		case XK_KP_End       : return GFX_KEY_END;

		case XK_Select       : return GFX_KEY_SELECT;
		case XK_Print        : return GFX_KEY_PRINT;
		case XK_Execute      : return GFX_KEY_EXECUTE;
		case XK_Insert       : return GFX_KEY_INSERT;
		case XK_KP_Insert    : return GFX_KEY_INSERT;
		case XK_Menu         : return GFX_KEY_MENU;
		case XK_Cancel       : return GFX_KEY_CANCEL;
		case XK_Help         : return GFX_KEY_HELP;
		case XK_Num_Lock     : return GFX_KEY_NUM_LOCK;
		case XK_KP_Space     : return GFX_KEY_SPACE;
		case XK_space        : return GFX_KEY_SPACE;

		case XK_KP_Enter     : return GFX_KEY_KP_RETURN;
		case XK_KP_Multiply  : return GFX_KEY_KP_MULTIPLY;
		case XK_KP_Add       : return GFX_KEY_KP_ADD;
		case XK_KP_Separator : return GFX_KEY_KP_SEPARATOR;
		case XK_KP_Subtract  : return GFX_KEY_KP_SUBTRACT;
		case XK_KP_Decimal   : return GFX_KEY_KP_DECIMAL;
		case XK_KP_Divide    : return GFX_KEY_KP_DIVIDE;

		case XK_Shift_L      : return GFX_KEY_SHIFT_LEFT;
		case XK_Shift_R      : return GFX_KEY_SHIFT_RIGHT;
		case XK_Control_L    : return GFX_KEY_CONTROL_LEFT;
		case XK_Control_R    : return GFX_KEY_CONTROL_RIGHT;
		case XK_Alt_L        : return GFX_KEY_ALT_LEFT;
		case XK_Alt_R        : return GFX_KEY_ALT_RIGHT;
		case XK_Super_L      : return GFX_KEY_SUPER_LEFT;
		case XK_Super_R      : return GFX_KEY_SUPER_RIGHT;
	}

	return GFX_KEY_UNKNOWN;
}

/******************************************************/
static void _gfx_x11_create_key_table(void)
{
	/* Get permitted keycodes and their symbols */
	int minKey, maxKey;
	XDisplayKeycodes(_gfx_x11.display, &minKey, &maxKey);
	maxKey = maxKey > GFX_X11_MAX_KEYCODE ? GFX_X11_MAX_KEYCODE : maxKey;

	int numKeys = maxKey - minKey + 1;

	int symbolsPerKey;
	KeySym* symbols = XGetKeyboardMapping(
		_gfx_x11.display,
		minKey,
		numKeys,
		&symbolsPerKey
	);

	/* Use the first symbol of all keycodes */
	size_t i;
	for(i = minKey; i <= maxKey; ++i) _gfx_x11.keys[i] = _gfx_x11_get_key(
		symbols[(i - minKey) * symbolsPerKey]);

	XFree(symbols);
}
Exemplo n.º 17
0
// Check whether the running window manager is EWMH-compliant
//
static void detectEWMH(void)
{
    Window* windowFromRoot = NULL;
    Window* windowFromChild = NULL;

    // First we need a couple of atoms, which should already be there
    Atom supportingWmCheck =
        XInternAtom(_glfw.x11.display, "_NET_SUPPORTING_WM_CHECK", True);
    Atom wmSupported =
        XInternAtom(_glfw.x11.display, "_NET_SUPPORTED", True);
    if (supportingWmCheck == None || wmSupported == None)
        return;

    // Then we look for the _NET_SUPPORTING_WM_CHECK property of the root window
    if (_glfwGetWindowProperty(_glfw.x11.root,
                               supportingWmCheck,
                               XA_WINDOW,
                               (unsigned char**) &windowFromRoot) != 1)
    {
        XFree(windowFromRoot);
        return;
    }

    // It should be the ID of a child window (of the root)
    // Then we look for the same property on the child window
    if (_glfwGetWindowProperty(*windowFromRoot,
                               supportingWmCheck,
                               XA_WINDOW,
                               (unsigned char**) &windowFromChild) != 1)
    {
        XFree(windowFromRoot);
        XFree(windowFromChild);
        return;
    }

    // It should be the ID of that same child window
    if (*windowFromRoot != *windowFromChild)
    {
        XFree(windowFromRoot);
        XFree(windowFromChild);
        return;
    }

    XFree(windowFromRoot);
    XFree(windowFromChild);

    // We are now fairly sure that an EWMH-compliant window manager is running

    Atom* supportedAtoms;
    unsigned long atomCount;

    // Now we need to check the _NET_SUPPORTED property of the root window
    // It should be a list of supported WM protocol and state atoms
    atomCount = _glfwGetWindowProperty(_glfw.x11.root,
                                       wmSupported,
                                       XA_ATOM,
                                       (unsigned char**) &supportedAtoms);

    // See which of the atoms we support that are supported by the WM

    _glfw.x11.NET_WM_STATE =
        getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE");
    _glfw.x11.NET_WM_STATE_FULLSCREEN =
        getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_FULLSCREEN");
    _glfw.x11.NET_WM_NAME =
        getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_NAME");
    _glfw.x11.NET_WM_ICON_NAME =
        getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_ICON_NAME");
    _glfw.x11.NET_WM_PID =
        getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_PID");
    _glfw.x11.NET_WM_PING =
        getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_PING");
    _glfw.x11.NET_ACTIVE_WINDOW =
        getSupportedAtom(supportedAtoms, atomCount, "_NET_ACTIVE_WINDOW");

    XFree(supportedAtoms);

    _glfw.x11.hasEWMH = GL_TRUE;
}
Exemplo n.º 18
0
	void X11Window::create(XVisualInfo *visual, DisplayWindowSite *new_site, const DisplayWindowDescription &desc)
	{
		site = new_site;

		// Reset all variables
		close_window();

		handle.screen = visual->screen;
		atoms = X11Atoms(handle.display);

		int disp_width_px = XDisplayWidth(handle.display, handle.screen);
		int disp_height_px = XDisplayHeight(handle.display, handle.screen);
		int disp_width_mm = XDisplayWidthMM(handle.display, handle.screen);

		// Get DPI of screen or use 96.0f if Xlib doesn't have a value.
		ppi = (disp_width_mm < 24) ? 96.0f : (25.4f * static_cast<float>(disp_width_px) / static_cast<float>(disp_width_mm));

		// Update pixel ratio.
		set_pixel_ratio(pixel_ratio);

		// Get X11 root window.
		auto _root_window = RootWindow(handle.display, handle.screen);

		// Get and validate initial window position and size.
		int win_x = desc.get_position().left * pixel_ratio;
		int win_y = desc.get_position().top * pixel_ratio;
		int win_width = desc.get_size().width * pixel_ratio;
		int win_height = desc.get_size().height * pixel_ratio;

		if (win_width <= 0)
			throw Exception("Invalid window width.");

		if (win_height <= 0)
			throw Exception("Invalid window height.");

		// Set values if fullscreen requested.
		if (desc.is_fullscreen())
		{
			win_x = 0;
			win_y = 0;
			win_width = disp_width_px;
			win_height = disp_height_px;
		}

		// Center window if position supplied is (-1, -1)
		if (win_x == -1 && win_y == -1)
		{
			win_x = (disp_width_px - win_width)/2 - 1;
			win_y = (disp_height_px - win_height)/2 - 1;
		}

		// Set minimum and maximum size
		this->resize_allowed = desc.get_allow_resize() || desc.is_fullscreen(); // Fullscreen mode needs a resizable window.
		if (resize_allowed)
		{
			minimum_size = Size(_ResizeMinimumSize_, _ResizeMinimumSize_);
			maximum_size = Size(0, 0); // No maximum size by default.
		}
		else
		{
			minimum_size = Size(win_width, win_height);
			maximum_size = Size(win_width, win_height);
		}

		// Setup X11 size hints.
		this->size_hints = XAllocSizeHints();
		if (size_hints == NULL)
			throw Exception("Failed to allocate X11 XSizeHints structure.");

		size_hints->flags       = PMinSize | (resize_allowed ? 0 : PMaxSize);
		size_hints->flags      |= PResizeInc | PBaseSize | PWinGravity;

		// x, y, width, height are obsolete.
		size_hints->flags      |= USSize | USPosition;	// See http://standards.freedesktop.org/wm-spec/wm-spec-latest.html#idm140200472522864

		size_hints->min_width   = minimum_size.width;
		size_hints->min_height  = minimum_size.height;
		size_hints->max_width   = maximum_size.width;
		size_hints->max_height  = maximum_size.height;
		size_hints->width_inc   = 1;
		size_hints->height_inc  = 1;
		size_hints->base_width  = win_width;
		size_hints->base_height = win_height;
		size_hints->win_gravity = NorthWestGravity;

		// Setup X11 colormap.
		//
		// The X.Org XServer implementation used on most systems requires that
		// a color-map be set for the window. Additionally, windows with a
		// different color-depth than its parent must have the border-pixel flag
		// set when creating them. Failure to do either will cause XCreateWindow()
		// to result in a BadMatch error.
		//
		// Source: stackoverflow.com/questions/3645632
		color_map = XCreateColormap(handle.display, _root_window, visual->visual, AllocNone);

		// Static popups are unresizable captionless popup windows.
		// These windows should not be decorated.
		bool is_static_popup = desc.is_popup() && !desc.has_caption() && !desc.get_allow_resize();

		// Tell X11 to perserve graphical content under small popup windows to avoid redraws.
		bool save_under = desc.is_popup() && ( (win_width * win_height) < (256 * 256 * pixel_ratio * pixel_ratio) );

		// Setup window attributes.
		XSetWindowAttributes attr = XSetWindowAttributes {
			.background_pixmap  = None, /* default */
			.background_pixel   =  0ul, /* default: undefined */
			.border_pixmap      = CopyFromParent, /* default */
			.border_pixel       =  0ul, /* see color_map details above */
			.bit_gravity        = ForgetGravity, /* default */
			.win_gravity        = NorthWestGravity, /* default */
			.backing_store      = NotUseful, /* default */
			.backing_planes     = -1ul, /* default */
			.backing_pixel      =  0ul, /* default */
			.save_under         = save_under ? True : False,
			.event_mask         = KeyPressMask
								| KeyReleaseMask
								| ButtonPressMask
								| ButtonReleaseMask
								| EnterWindowMask
								| LeaveWindowMask
								| PointerMotionMask
								| KeymapStateMask
								| ExposureMask
								// | VisibilityChangeMask
								| StructureNotifyMask
								| FocusChangeMask
								| PropertyChangeMask ,
			.do_not_propagate_mask  = NoEventMask, /* default */
			.override_redirect      = is_static_popup ? True : False,
			.colormap               = color_map, /* see color_map details above */
			.cursor                 = None /* default; Let X11 handle the cursor for now. */
		};

		this->system_cursor = XCreateFontCursor(handle.display, XC_left_ptr); // This is allowed to fail

		log_event("debug", "clan::X11Window::create(): Creating window...");
		log_event("debug", "    x%1 y%2 w%3 h%4 b%5 d%6", win_x, win_y, win_width, win_height, border_width, visual->depth);
		log_event("debug", "    a.su%1, a.od%2", save_under, is_static_popup);

		// Create window
		handle.window = XCreateWindow(
				handle.display, _root_window,
				win_x, win_y, win_width, win_height, border_width,
				visual->depth, InputOutput, visual->visual,
				CWBorderPixel | CWOverrideRedirect | CWSaveUnder | CWEventMask | CWColormap,
				&attr
				);

		if (!handle.window)
			throw Exception("Unable to create the X11 window");

		if (!desc.get_owner().is_null())
		{
			DisplayWindow owner = desc.get_owner();
			XSetTransientForHint(handle.display, handle.window, owner.get_handle().window);
		}

		// Setup the hidden cursor (Maybe this should be done only once when required)
		char data[64]; // 8x8
		memset(data, 0, 64);

		XColor black_color;
		memset(&black_color, 0, sizeof(black_color));

		cursor_bitmap = XCreateBitmapFromData(handle.display, handle.window, data, 8, 8);
		hidden_cursor = XCreatePixmapCursor(handle.display, cursor_bitmap, cursor_bitmap, &black_color, &black_color, 0,0);

		// Set title of window:
		set_title(desc.get_title());

		{   // Inform the window manager who we are, so it can kill us if we're not good for its universe.
			Atom atom;
			int32_t pid = getpid();
			if (pid > 0)
			{
				atom = atoms.get_atom(handle.display, "_NET_WM_PID", False);
				XChangeProperty(handle.display, handle.window, atom, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &pid, 1);
			}

			char hostname[256];
			if (gethostname(hostname, sizeof(hostname)) > -1)
			{
				hostname[255] = 0;
				atom = atoms.get_atom(handle.display, "WM_CLIENT_MACHINE", False);
				XChangeProperty(handle.display, handle.window, atom, XA_STRING, 8, PropModeReplace, (unsigned char *) hostname, strlen(hostname));
			}
		}

		// Set-up window type/styling.
		// TODO Support more window types, broaden ClanLib window type support, etc.
		if (atoms["_NET_WM_WINDOW_TYPE"] != None)
		{
			Atom type = None;
			std::string name;

			if (desc.is_dialog())
			{
				name = "_NET_WM_WINDOW_TYPE_DIALOG";
				type = atoms[name];
			}
			else if (desc.is_popup())
			{
				if (is_static_popup)
				{
					name = "_NET_WM_WINDOW_TYPE_TOOLTIP";
					type = atoms[name];
				}
				else if (desc.has_caption()) // A pop-up with title bar -> utility
				{
					name = "_NET_WM_WINDOW_TYPE_UTILITY";
					type = atoms[name];
				} // else, a pop-up without a title bar -> popup-menu, combo, dropdown, tooltip, ...

				if (type == None) { name = "_NET_WM_WINDOW_TYPE_POPUP_MENU"; type = atoms[name]; }
				if (type == None) { name = "_NET_WM_WINDOW_TYPE_COMBO"; type = atoms[name]; }
				if (type == None) { name = "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"; type = atoms[name]; }
			} // else if (desc.is_normal())

			// Fallback to normal window type if WM doesn't support what we want.
			if (type == None) { name = "_NET_WM_WINDOW_TYPE_NORMAL"; type = atoms[name]; }

			if (type != None) // Ensure selected type exists.
			{
				XChangeProperty(handle.display, handle.window, atoms["_NET_WM_WINDOW_TYPE"], XA_ATOM, 32, PropModeReplace, (unsigned char *)&type, 1);
				log_event("debug", "clan::X11Window::create(): Creating window of type '%1'.", name);
			}
			else
			{
				log_event("debug", "clan::X11Window::create(): Failed to find a suitable window type.");
			}
		}
		else
		{
			log_event("debug", "clan::X11Window::create(): _NET_WM_WINDOW_TYPE does not exist.");
		}

		// Set size hints
		XSetWMNormalHints(handle.display, handle.window, size_hints);

		{	// Subscribe to WM events.
			Atom protocol = atoms["WM_DELETE_WINDOW"];
			Status result = XSetWMProtocols(handle.display, handle.window, &protocol, 1);
			if (result == 0)
				log_event("debug", "clan::X11Window::create(): Failed to set WM_PROTOCOLS.");
		}

		{	// Make auto-repeat keys detectable.
			Bool supports_detectable_autorepeat;
			XkbSetDetectableAutoRepeat(handle.display, True, &supports_detectable_autorepeat);
		}

		{	// Make window full-screen if requested.
			if (atoms["_NET_WM_STATE"] == None && atoms["_NET_WM_STATE_FULLSCREEN"])
			{
				fullscreen = false;
				log_event("debug", "clan::X11Window: Fullscreen not supported by WM.");
			}
			else
			{
				fullscreen = desc.is_fullscreen();
			}

			if (fullscreen)
			{
				Atom state = atoms["_NET_WM_STATE_FULLSCREEN"];
				XChangeProperty(handle.display, handle.window, atoms["_NET_WM_STATE"], XA_ATOM, 32, PropModeReplace, (unsigned char *)&state, 1);
			}
		}

		update_frame_extents();

		auto new_client_area = desc.get_position_client_area() // supplied position is at ? client area : window area;
			? Rect::xywh(win_x, win_y, win_width, win_height)
			: Rect::xywh(win_x + frame_extents.left, win_y + frame_extents.right, win_width, win_height)
			;

		process_window_resize(new_client_area);

		// Set window visibility
		if (desc.is_visible())
		{
			show(false);
		}

		// Setup the clipboard
		clipboard.setup();

		// Go looking for joysticks:
		setup_joysticks();
	}

	void X11Window::update_frame_extents()
	{
		frame_extents = Rect { border_width, border_width, border_width, border_width };

		if (atoms["_NET_FRAME_EXTENTS"] == None)
			return;

		// Request frame extents from WM.
		if (atoms["_NET_REQUEST_FRAME_EXTENTS"] != None)
		{
			XEvent event;
			memset(&event, 0, sizeof(event));

			event.type = ClientMessage;
			event.xclient.window = handle.window;
			event.xclient.format = 32;
			event.xclient.message_type = atoms["_NET_REQUEST_FRAME_EXTENTS"];

			XSendEvent(handle.display, RootWindow(handle.display, handle.screen), False, SubstructureNotifyMask | SubstructureRedirectMask, &event);

			int timer = 10;
			while(true)
			{
				if (timer < 0)
				{
					log_event("debug", "clan::X11Window: Your window manager has a broken _NET_REQUEST_FRAME_EXTENTS implementation.");
					break;
				}

				if (XCheckMaskEvent(handle.display, PropertyNotify, &event))
				{
					break;
				}

				clan::System::sleep(5);
				timer--;
			}
		}

		unsigned long  item_count;
		// _NET_FRAME_EXTENTS, left, right, top, bottom, CARDINAL[4]/32
		unsigned char *data = atoms.get_property(handle.window, "_NET_FRAME_EXTENTS", item_count);
		if (data == NULL)
			return;

		if (item_count >= 4)
		{
			long *cardinal = (long *)data;
			frame_extents.left   = cardinal[0];
			frame_extents.right  = cardinal[1];
			frame_extents.top    = cardinal[2];
			frame_extents.bottom = cardinal[3];
		}

		XFree(data);
	}
Exemplo n.º 19
0
/*
 *  Function for selecting all interesting events on a given 
 *  (tree of) window(s).
 */
static void 
selectEvents (Window window, Bool substructureOnly)
{
  Window            root;              /* root window of the window */
  Window            parent;            /* parent of the window      */
  Window*           children;          /* children of the window    */
  unsigned          nofChildren = 0;   /* number of children        */
  unsigned          i;                 /* loop counter              */
  XWindowAttributes attribs;           /* attributes of the window  */

  if( xautolock_ignoreWindow( window ))
      return;
 /*
  *  Start by querying the server about the root and parent windows.
  */
  if (!XQueryTree (queue.display, window, &root, &parent,
                   &children, &nofChildren))
  {
    return;
  }

  if (nofChildren) (void) XFree ((char*) children);

 /*
  *  Build the appropriate event mask. The basic idea is that we don't
  *  want to interfere with the normal event propagation mechanism if
  *  we don't have to.
  *
  *  On the root window, we need to ask for both substructureNotify 
  *  and KeyPress events. On all other windows, we always need 
  *  substructureNotify, but only need Keypress if some other client
  *  also asked for them, or if they are not being propagated up the
  *  window tree.
  */
#if 0
  if (substructureOnly)
  {
    (void) XSelectInput (queue.display, window, SubstructureNotifyMask);
  }
  else
  {
    if (parent == None) /* the *real* rootwindow */
    {
      attribs.all_event_masks = 
      attribs.do_not_propagate_mask = KeyPressMask;
    }
    else if (!XGetWindowAttributes (queue.display, window, &attribs))
#else
    {
    if (!XGetWindowAttributes (queue.display, window, &attribs))
#endif
    {
      return;
    }

#if 0
    (void) XSelectInput (queue.display, window, 
                           SubstructureNotifyMask
                         | (  (  attribs.all_event_masks
                               | attribs.do_not_propagate_mask)
                            & KeyPressMask));
#else
    {
    int mask = SubstructureNotifyMask | attribs.your_event_mask;
    if( !substructureOnly )
        {
        mask |=            (  (  attribs.all_event_masks
                               | attribs.do_not_propagate_mask)
                            & KeyPressMask  );
        }
    (void) XSelectInput (queue.display, window, mask );
    }
#endif

  }

 /*
  *  Now ask for the list of children again, since it might have changed
  *  in between the last time and us selecting SubstructureNotifyMask.
  *
  *  There is a (very small) chance that we might process a subtree twice:
  *  child windows that have been created after our XSelectinput() has
  *  been processed but before we get to the XQueryTree() bit will be 
  *  in this situation. This is harmless. It could be avoided by using
  *  XGrabServer(), but that'd be an impolite thing to do, and since it
  *  isn't required...
  */
  if (!XQueryTree (queue.display, window, &root, &parent,
                   &children, &nofChildren))
  {
    return;
  }

 /*
  *  Now do the same thing for all children.
  */
  for (i = 0; i < nofChildren; ++i)
  {
    selectEvents (children[i], substructureOnly);
  }

  if (nofChildren) (void) XFree ((char*) children);
}

#if 0
/*
 *  Function for processing any events that have come in since 
 *  last time. It is crucial that this function does not block
 *  in case nothing interesting happened.
 */
void
processEvents (void)
{
  while (XPending (queue.display))
  {
    XEvent event;

    if (XCheckMaskEvent (queue.display, SubstructureNotifyMask, &event))
    {
      if (event.type == CreateNotify)
      {
        addToQueue (event.xcreatewindow.window);
      }
    }
    else
    {
      (void) XNextEvent (queue.display, &event);
    }

   /*
    *  Reset the triggers if and only if the event is a
    *  KeyPress event *and* was not generated by XSendEvent().
    */
    if (   event.type == KeyPress
        && !event.xany.send_event)
    {
      resetTriggers ();
    }
  }

 /*
  *  Check the window queue for entries that are older than
  *  CREATION_DELAY seconds.
  */
  processQueue ((time_t) CREATION_DELAY);
}
#else
void xautolock_processEvent( XEvent* event )
{
      if (event->type == CreateNotify)
      {
        addToQueue (event->xcreatewindow.window);
      }
   /*
    *  Reset the triggers if and only if the event is a
    *  KeyPress event *and* was not generated by XSendEvent().
    */
    if (   event->type == KeyPress
        && !event->xany.send_event)
    {
      xautolock_resetTriggers ();
    }
}

void xautolock_processQueue()
{
 /*
  *  Check the window queue for entries that are older than
  *  CREATION_DELAY seconds.
  */
  processQueue ((time_t) CREATION_DELAY);
}
static int
watch (Display *dpy)
{
  char *v = 0;
  Window window = RootWindow (dpy, 0);
  XWindowAttributes xgwa;
  XEvent event;
  PROP32 *last = 0;

  if (v) free (v);
  XGetWindowAttributes (dpy, window, &xgwa);
  XSelectInput (dpy, window, xgwa.your_event_mask | PropertyChangeMask);

  while (1)
    {
      XNextEvent (dpy, &event);
      if (event.xany.type == PropertyNotify &&
          event.xproperty.state == PropertyNewValue &&
          event.xproperty.atom == XA_SCREENSAVER_STATUS)
        {
	  Atom type;
	  int format;
	  unsigned long nitems, bytesafter;
          unsigned char *dataP = 0;

	  if (XGetWindowProperty (dpy,
                                  RootWindow (dpy, 0),  /* always screen #0 */
				  XA_SCREENSAVER_STATUS,
				  0, 999, False, XA_INTEGER,
				  &type, &format, &nitems, &bytesafter,
				  &dataP)
	      == Success
	      && type
	      && dataP)
	    {
              time_t tt;
              char *s;
              Bool changed = False;
              Bool running = False;
              PROP32 *data = (PROP32 *) dataP;

              if (type != XA_INTEGER || nitems < 3)
                {
                STATUS_LOSE:
                  if (last) XFree (last);
                  if (data) XFree (data);
                  fprintf (stderr, "%s: bad status format on root window.\n",
                           progname);
                  return -1;
                }
                  
              tt = (time_t) data[1];
              if (tt <= (time_t) 666000000L) /* early 1991 */
                goto STATUS_LOSE;

              s = ctime(&tt);
              if (s[strlen(s)-1] == '\n')
                s[strlen(s)-1] = 0;

              if (!last || data[0] != last[0])
                {
                  /* State changed. */
                  if (data[0] == XA_BLANK)
                    printf ("BLANK %s\n", s);
                  else if (data[0] == XA_LOCK)
                    printf ("LOCK %s\n", s);
                  else if (data[0] == 0)
                    printf ("UNBLANK %s\n", s);
                  else
                    goto STATUS_LOSE;
                }

              if (!last)
                changed = True;
              else
                {
                  int i;
                  for (i = 2; i < nitems; i++)
                    {
                      if (data[i] != last[i])
                        changed = True;
                      if (data[i])
                        running = True;
                    }
                }

              if (running && changed)
                {
                  int i;
                  fprintf (stdout, "RUN");
                  for (i = 2; i < nitems; i++)
                    fprintf (stdout, " %d", (int) data[i]);
                  fprintf (stdout, "\n");
                }

              fflush (stdout);

              if (last) XFree (last);
              last = data;
	    }
	  else
	    {
	      if (last) XFree (last);
	      if (dataP) XFree (dataP);
	      fprintf (stderr, "%s: no saver status on root window.\n",
		       progname);
	      return -1;
	    }
        }
    }
}
Exemplo n.º 21
0
COffscreenGLContext::COffscreenGLContext()
{
	if (!mainGlActiveTexture)
		mainGlActiveTexture = (PFNGLACTIVETEXTUREPROC)glXGetProcAddress((const GLubyte*)"glActiveTexture");

	//! Get MainCtx & X11-Display
	GLXContext mainCtx = glXGetCurrentContext();
	display = glXGetCurrentDisplay();
	//GLXDrawable mainDrawable = glXGetCurrentDrawable();
	if(!mainCtx)
		throw opengl_error("Couldn't create an offscreen GL context: glXGetCurrentContext failed!");

	if (!display)
		throw opengl_error("Couldn't create an offscreen GL context: Couldn't determine display!");

	int scrnum = XDefaultScreen(display);

	//! Create a FBConfig
	int nelements = 0;
	const int fbattribs[] = {
		GLX_RENDER_TYPE, GLX_RGBA_BIT,
		GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
		GLX_BUFFER_SIZE, 32,
		GLX_DEPTH_SIZE, 24,
		GLX_STENCIL_SIZE, 8,
		None
	};
	GLXFBConfig* fbcfg = glXChooseFBConfig(display, scrnum, (const int*)fbattribs, &nelements);
	if (!fbcfg || (nelements == 0))
		throw opengl_error("Couldn't create an offscreen GL context: glXChooseFBConfig failed!");


	//! Create a pbuffer (each render context needs a drawable)
	const int pbuf_attribs[] = {
		GLX_PBUFFER_WIDTH, 1,
		GLX_PBUFFER_HEIGHT, 1,
		GLX_PRESERVED_CONTENTS, false,
		None
	};
	pbuf = glXCreatePbuffer(display, fbcfg[0], (const int*)pbuf_attribs);
	if (!pbuf)
		throw opengl_error("Couldn't create an offscreen GL context: glXCreatePbuffer failed!");

/*
	//Create a GL 3.0 context
	const int ctx_attribs[] = {
		//GLX_CONTEXT_MAJOR_VERSION_ARB, 2,
		//GLX_CONTEXT_MINOR_VERSION_ARB, 0,
		GLX_CONTEXT_FLAGS_ARB,
			GLX_CONTEXT_DEBUG_BIT_ARB,
			//GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
		None
	};

	workerCtx = glXCreateContextAttribsARB(display, fbcfg[0], mainCtx, true, ctx_attribs);
*/

	//! Create render context
	workerCtx = glXCreateNewContext(display, fbcfg[0], GLX_RGBA_TYPE, mainCtx, true);
	if (!workerCtx)
		throw opengl_error("Couldn't create an offscreen GL context: glXCreateNewContext failed!");

	XFree(fbcfg);
}
Exemplo n.º 22
0
/**
 * find a calibratable touchscreen device (using XInput)
 *
 * if pre_device is NULL, the last calibratable device is selected.
 * retuns number of devices found,
 * the data of the device is returned in the last 3 function parameters
 */
int Calibrator::find_device(const char* pre_device, bool list_devices,
        XID& device_id, const char*& device_name, XYinfo& device_axys)
{
    bool pre_device_is_id = true;
    bool pre_device_is_sysfs = false;
    int found = 0;

    Display* display = XOpenDisplay(NULL);
    if (display == NULL) {
        fprintf(stderr, "Unable to connect to X server\n");
        exit(1);
    }

    int xi_opcode, event, error;
    if (!XQueryExtension(display, "XInputExtension", &xi_opcode, &event, &error)) {
        fprintf(stderr, "X Input extension not available.\n");
        exit(1);
    }

    // verbose, get Xi version
    if (verbose) {
        XExtensionVersion *version = XGetExtensionVersion(display, INAME);

        if (version && (version != (XExtensionVersion*) NoSuchExtension)) {
            printf("DEBUG: %s version is %i.%i\n",
                INAME, version->major_version, version->minor_version);
            XFree(version);
        }
    }

    if (pre_device != NULL) {
        // check whether the pre_device is an ID (only digits)
        int len = strlen(pre_device);
        for (int loop=0; loop<len; loop++) {
            if (!isdigit(pre_device[loop])) {
                pre_device_is_id = false;
                break;
            }
        }
    }

    std::string pre_device_sysfs;
    if (pre_device != NULL && !pre_device_is_id) {
        /* avoid overflow below - 10000 devices should be OK */
        if ( strlen(pre_device) < strlen("event") + 4 &&
             strncmp(pre_device, "event", strlen("event")) == 0 ) {
            // check whether the pre_device is an sysfs-path name
            char filename[40]; // actually 35, but hey...
            (void) sprintf(filename, "%s/%s/%s", SYSFS_INPUT, pre_device, SYSFS_DEVNAME);

            std::ifstream ifile(filename);
            if (ifile.is_open()) {
                if (!ifile.eof()) {
                    pre_device_is_sysfs = true;
                    std::getline(ifile, pre_device_sysfs);
                    ifile.close();
                }
            }
        }
    }

    if (verbose)
        printf("DEBUG: Skipping virtual master devices and devices without axis valuators.\n");
    int ndevices;
    XDeviceInfoPtr list, slist;
    slist=list=(XDeviceInfoPtr) XListInputDevices (display, &ndevices);
    for (int i=0; i<ndevices; i++, list++)
    {
        if (list->use == IsXKeyboard || list->use == IsXPointer) // virtual master device
            continue;

        // if we are looking for a specific device
        if (pre_device != NULL) {
            if ((pre_device_is_id && list->id == (XID) atoi(pre_device)) ||
                (!pre_device_is_id && strcmp(list->name, pre_device_is_sysfs ? pre_device_sysfs.c_str() : pre_device ) == 0)) {
                // OK, fall through
            } else {
                // skip, not this device
                continue;
            }
        }

        XAnyClassPtr any = (XAnyClassPtr) (list->inputclassinfo);
        for (int j=0; j<list->num_classes; j++)
        {

            if (any->c_class == ValuatorClass)
            {
                XValuatorInfoPtr V = (XValuatorInfoPtr) any;
                XAxisInfoPtr ax = (XAxisInfoPtr) V->axes;

                if (V->mode != Absolute) {
                    if (verbose)
                        printf("DEBUG: Skipping device '%s' id=%i, does not report Absolute events.\n",
                            list->name, (int)list->id);
                } else if (V->num_axes < 2 ||
                    (ax[0].min_value == -1 && ax[0].max_value == -1) ||
                    (ax[1].min_value == -1 && ax[1].max_value == -1)) {
                    if (verbose)
                        printf("DEBUG: Skipping device '%s' id=%i, does not have two calibratable axes.\n",
                            list->name, (int)list->id);
                } else {
                    /* a calibratable device (has 2 axis valuators) */
                    found++;
                    device_id = list->id;
                    device_name = my_strdup(list->name);
                    device_axys.x.min = ax[0].min_value;
                    device_axys.x.max = ax[0].max_value;
                    device_axys.y.min = ax[1].min_value;
                    device_axys.y.max = ax[1].max_value;

                    if (list_devices)
                        printf("Device \"%s\" id=%i\n", device_name, (int)device_id);
                }

            }

            /*
             * Increment 'any' to point to the next item in the linked
             * list.  The length is in bytes, so 'any' must be cast to
             * a character pointer before being incremented.
             */
            any = (XAnyClassPtr) ((char *) any + any->length);
        }

    }
    XFreeDeviceList(slist);
    XCloseDisplay(display);

    return found;
}
Exemplo n.º 23
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;
}
Exemplo n.º 24
0
/*
 * Class:     jogamp_nativewindow_x11_X11Lib
 * Method:    CreateWindow
 * Signature: (JJIIIIZZ)J
 */
JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateWindow
  (JNIEnv *env, jclass unused, jlong parent, jlong display, jint screen_index, jint visualID, jint width, jint height, jboolean input, jboolean visible)
{
    Display * dpy  = (Display *)(intptr_t)display;
    int       scrn_idx = (int)screen_index;
    Window root = RootWindow(dpy, scrn_idx);
    Window  windowParent = (Window) parent;
    Window  window = 0;

    XVisualInfo visualTemplate;
    XVisualInfo *pVisualQuery = NULL;
    Visual *visual = NULL;
    int depth;

    XSetWindowAttributes xswa;
    unsigned long attrMask;
    int n;

    Screen* scrn;

    if(NULL==dpy) {
        NativewindowCommon_FatalError(env, "invalid display connection..");
        return 0;
    }

    if(visualID<0) {
        NativewindowCommon_throwNewRuntimeException(env, "invalid VisualID ..");
        return 0;
    }

    NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 1, errorHandlerQuiet, 0);

    scrn = ScreenOfDisplay(dpy, scrn_idx);
    if(0==windowParent) {
        windowParent = root;
    }

    // try given VisualID on screen
    memset(&visualTemplate, 0, sizeof(XVisualInfo));
    visualTemplate.screen = scrn_idx;
    visualTemplate.visualid = (VisualID)visualID;
    pVisualQuery = XGetVisualInfo(dpy, VisualIDMask|VisualScreenMask, &visualTemplate,&n);
    if(pVisualQuery!=NULL) {
        visual   = pVisualQuery->visual;
        depth    = pVisualQuery->depth;
        visualID = (jint)pVisualQuery->visualid;
        XFree(pVisualQuery);
        pVisualQuery=NULL;
    }
    DBG_PRINT( "X11: [CreateWindow] trying given (dpy %p, screen %d, visualID: %d, parent %p) found: %p\n", dpy, scrn_idx, (int)visualID, windowParent, visual);

    if (visual==NULL)
    { 
        // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, errorHandlerQuiet, 1);
        NativewindowCommon_throwNewRuntimeException(env, "could not query Visual by given VisualID, bail out!");
        return 0;
    } 

    if(pVisualQuery!=NULL) {
        XFree(pVisualQuery);
        pVisualQuery=NULL;
    }


    attrMask  = ( CWBackingStore | CWBackingPlanes | CWBackingPixel | CWBackPixmap | 
                  CWBorderPixel | CWColormap | CWOverrideRedirect ) ;

    memset(&xswa, 0, sizeof(xswa));
    xswa.override_redirect = False; // use the window manager, always
    xswa.border_pixel = 0;
    xswa.background_pixmap = None;
    xswa.backing_store=NotUseful; /* NotUseful, WhenMapped, Always */
    xswa.backing_planes=0;        /* planes to be preserved if possible */
    xswa.backing_pixel=0;         /* value to use in restoring planes */
    if( input ) {
        xswa.event_mask  = X11_MOUSE_EVENT_MASK;
        xswa.event_mask |= KeyPressMask | KeyReleaseMask ;
    }
    if( visible ) {
        xswa.event_mask |= FocusChangeMask | SubstructureNotifyMask | StructureNotifyMask | ExposureMask ;
    }

    xswa.colormap = XCreateColormap(dpy,
                                    windowParent,
                                    visual,
                                    AllocNone);

    window = XCreateWindow(dpy,
                           windowParent,
                           0, 0, // only a hint, WM most likely will override
                           width, height,
                           0, // border width
                           depth,
                           InputOutput,
                           visual,
                           attrMask,
                           &xswa);
    if(0==window) {
        NativewindowCommon_throwNewRuntimeException(env, "could not create Window, bail out!");
        return 0;
    }

    NativewindowX11_setNormalWindowEWMH(dpy, window);
    NativewindowX11_setDecorations(dpy, window, False);

    if( visible ) {
        XEvent event;

        XMapWindow(dpy, window);
    }

    XSync(dpy, False);

    if( !input ) {
        XSelectInput(dpy, window, 0); // no events
    }

    // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, errorHandlerQuiet, 1);

    DBG_PRINT( "X11: [CreateWindow] created window %p on display %p\n", window, dpy);

    return (jlong) window;
}
Exemplo n.º 25
0
Arquivo: ewmh.c Projeto: n4cht/kwm
/** Manage the client hints
 *\param c Client pointer
*/
void
ewmh_manage_window_type(Client *c)
{
     Atom *atom, rf;
     int f;
     ulong n, il, i;
     uchar *data = NULL;
     long ldata[5] = { 0 };

     if(XGetWindowProperty(dpy, c->win, net_atom[net_wm_window_type], 0L, 0x7FFFFFFFL,
                           False, XA_ATOM, &rf, &f, &n, &il, &data) == Success && n)
     {
          atom = (Atom*)data;

          for(i = 0; i < n; ++i)
          {
               /* Manage _NET_WM_WINDOW_TYPE_DOCK & _NET_WM_WINDOW_TYPE_SPLASH */
               if(atom[i] == net_atom[net_wm_window_type_dock]
                  || atom[i] == net_atom[net_wm_window_type_splash])
               {
                    /* Unmap frame, decoration.. */
                    client_unmap(c);

                    /* Map only window */
                    XMapWindow(dpy, c->win);

                    /* Reparent it to ROOT win */
                    XReparentWindow(dpy, c->win, ROOT, c->geo.x, c->geo.y);
                    XRaiseWindow(dpy, c->win);

                    c->flags |= DockFlag;
               }
               /* MANAGE _NET_WM_WINDOW_TYPE_DIALOG */
               else if(atom[i] == net_atom[net_wm_window_type_dialog])
               {
                    c->flags |= FreeFlag;
                    c->flags &= ~(TileFlag | MaxFlag | LMaxFlag);
                    client_moveresize(c, c->ogeo, True);
                    client_focus(c);
                    tags[selscreen][seltag[selscreen]].layout.func(selscreen);
               }
          }
          XFree(data);
     }

     /* Get NET_WM_STATE set without sending client message event */
     if(XGetWindowProperty(dpy, c->win, net_atom[net_wm_state], 0L, 0x7FFFFFFFL,
                           False, XA_ATOM, &rf, &f, &n, &il, &data) == Success && n)
     {
          atom = (Atom*)data;

          for(i = 0; i < n; ++i)
          {
               ldata[0] = _NET_WM_STATE_ADD;
               ldata[1] = atom[i];
               ewmh_manage_net_wm_state(ldata, c);
          }
          XFree(data);
     }

     return;
}
Exemplo n.º 26
0
Arquivo: vo_xv.c Projeto: andre-d/mpv
static void draw_osd(struct vo *vo, struct osd_state *osd)
{
    struct xvctx *ctx = vo->priv;

    struct mp_image img = get_xv_buffer(vo, ctx->current_buf);

    struct mp_osd_res res = {
        .w = ctx->image_width,
        .h = ctx->image_height,
        .display_par = 1.0 / vo->aspdat.par,
    };

    osd_draw_on_image(osd, res, osd->vo_pts, 0, &img);
}

static void wait_for_completion(struct vo *vo, int max_outstanding)
{
#if HAVE_SHM && HAVE_XEXT
    struct xvctx *ctx = vo->priv;
    struct vo_x11_state *x11 = vo->x11;
    if (ctx->Shmem_Flag) {
        while (x11->ShmCompletionWaitCount > max_outstanding) {
            if (!ctx->Shm_Warned_Slow) {
                MP_WARN(vo, "X11 can't keep up! Waiting"
                        " for XShm completion events...\n");
                ctx->Shm_Warned_Slow = 1;
            }
            mp_sleep_us(1000);
            vo_x11_check_events(vo);
        }
    }
#endif
}

static void flip_page(struct vo *vo)
{
    struct xvctx *ctx = vo->priv;
    put_xvimage(vo, ctx->xvimage[ctx->current_buf]);

    /* remember the currently visible buffer */
    ctx->current_buf = (ctx->current_buf + 1) % ctx->num_buffers;

    if (!ctx->Shmem_Flag)
        XSync(vo->x11->display, False);
}

static mp_image_t *get_screenshot(struct vo *vo)
{
    struct xvctx *ctx = vo->priv;
    if (!ctx->original_image)
        return NULL;

    return mp_image_new_ref(ctx->original_image);
}

// Note: redraw_frame() can call this with NULL.
static void draw_image(struct vo *vo, mp_image_t *mpi)
{
    struct xvctx *ctx = vo->priv;

    wait_for_completion(vo, ctx->num_buffers - 1);

    struct mp_image xv_buffer = get_xv_buffer(vo, ctx->current_buf);
    if (mpi) {
        mp_image_copy(&xv_buffer, mpi);
    } else {
        mp_image_clear(&xv_buffer, 0, 0, xv_buffer.w, xv_buffer.h);
    }

    mp_image_setrefp(&ctx->original_image, mpi);
}

static int redraw_frame(struct vo *vo)
{
    struct xvctx *ctx = vo->priv;

    draw_image(vo, ctx->original_image);
    return true;
}

static int query_format(struct vo *vo, uint32_t format)
{
    struct xvctx *ctx = vo->priv;
    uint32_t i;
    int flag = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW;

    int fourcc = find_xv_format(format);
    if (fourcc) {
        for (i = 0; i < ctx->formats; i++) {
            if (ctx->fo[i].id == fourcc)
                return flag;
        }
    }
    return 0;
}

static void uninit(struct vo *vo)
{
    struct xvctx *ctx = vo->priv;
    int i;

    talloc_free(ctx->original_image);

    if (ctx->ai)
        XvFreeAdaptorInfo(ctx->ai);
    ctx->ai = NULL;
    if (ctx->fo) {
        XFree(ctx->fo);
        ctx->fo = NULL;
    }
    for (i = 0; i < ctx->num_buffers; i++)
        deallocate_xvimage(vo, i);
    // uninit() shouldn't get called unless initialization went past vo_init()
    vo_x11_uninit(vo);
}

static int preinit(struct vo *vo)
{
    XvPortID xv_p;
    int busy_ports = 0;
    unsigned int i;
    struct xvctx *ctx = vo->priv;
    int xv_adaptor = ctx->cfg_xv_adaptor;

    if (!vo_x11_init(vo))
        return -1;

    struct vo_x11_state *x11 = vo->x11;

    /* check for Xvideo extension */
    unsigned int ver, rel, req, ev, err;
    if (Success != XvQueryExtension(x11->display, &ver, &rel, &req, &ev, &err)) {
        MP_ERR(vo, "Xv not supported by this X11 version/driver\n");
        goto error;
    }

    /* check for Xvideo support */
    if (Success !=
        XvQueryAdaptors(x11->display, DefaultRootWindow(x11->display),
                        &ctx->adaptors, &ctx->ai)) {
        MP_ERR(vo, "XvQueryAdaptors failed.\n");
        goto error;
    }

    /* check adaptors */
    if (ctx->xv_port) {
        int port_found;

        for (port_found = 0, i = 0; !port_found && i < ctx->adaptors; i++) {
            if ((ctx->ai[i].type & XvInputMask)
                && (ctx->ai[i].type & XvImageMask)) {
                for (xv_p = ctx->ai[i].base_id;
                     xv_p < ctx->ai[i].base_id + ctx->ai[i].num_ports;
                     ++xv_p) {
                    if (xv_p == ctx->xv_port) {
                        port_found = 1;
                        break;
                    }
                }
            }
        }
        if (port_found) {
            if (XvGrabPort(x11->display, ctx->xv_port, CurrentTime))
                ctx->xv_port = 0;
        } else {
            MP_WARN(vo, "Invalid port parameter, overriding with port 0.\n");
            ctx->xv_port = 0;
        }
    }

    for (i = 0; i < ctx->adaptors && ctx->xv_port == 0; i++) {
        /* check if adaptor number has been specified */
        if (xv_adaptor != -1 && xv_adaptor != i)
            continue;

        if ((ctx->ai[i].type & XvInputMask) && (ctx->ai[i].type & XvImageMask)) {
            for (xv_p = ctx->ai[i].base_id;
                 xv_p < ctx->ai[i].base_id + ctx->ai[i].num_ports; ++xv_p)
                if (!XvGrabPort(x11->display, xv_p, CurrentTime)) {
                    ctx->xv_port = xv_p;
                    MP_VERBOSE(vo, "Using Xv Adapter #%d (%s)\n",
                               i, ctx->ai[i].name);
                    break;
                } else {
                    MP_WARN(vo, "Could not grab port %i.\n", (int) xv_p);
                    ++busy_ports;
                }
        }
    }
    if (!ctx->xv_port) {
        if (busy_ports)
            MP_ERR(vo,
                   "Could not find free Xvideo port - maybe another process is already\n"\
                   "using it. Close all video applications, and try again. If that does\n"\
                   "not help, see 'mpv -vo help' for other (non-xv) video out drivers.\n");
        else
            MP_ERR(vo,
                   "It seems there is no Xvideo support for your video card available.\n"\
                   "Run 'xvinfo' to verify its Xv support and read\n"\
                   "DOCS/HTML/en/video.html#xv!\n"\
                   "See 'mpv -vo help' for other (non-xv) video out drivers.\n"\
                   "Try -vo x11.\n");
        goto error;
    }

    if (!xv_init_colorkey(vo)) {
        goto error;             // bail out, colorkey setup failed
    }
    xv_enable_vsync(vo);
    xv_get_max_img_dim(vo, &ctx->max_width, &ctx->max_height);

    ctx->fo = XvListImageFormats(x11->display, ctx->xv_port,
                                 (int *) &ctx->formats);

    return 0;

  error:
    uninit(vo);                 // free resources
    return -1;
}
Exemplo n.º 27
0
static void x11video_prepare(MSFilter *f){
	X11Video *s=(X11Video*)f->data;
	unsigned int n;
	unsigned int nadaptors;
	int i;
	XvAdaptorInfo *xai=NULL;
	XvPortID port=-1;
	int imgfmt_id=0;
	XShmSegmentInfo *shminfo=&s->shminfo;
	XWindowAttributes wa;

	if (s->display==NULL) return;
	if (s->window_id==0){
		if(s->auto_window) {
			s->window_id=createX11Window(s);
		}
		if (s->window_id==0) return;
		s->own_window=TRUE;
	}

	/* Make sure X11 window is ready to use*/
	XSync(s->display, False);

	if (s->own_window==FALSE){
		/*we need to register for resize events*/
		XSelectInput(s->display,s->window_id,StructureNotifyMask);
	}
	XGetWindowAttributes(s->display,s->window_id,&wa);
	XClearWindow(s->display,s->window_id);
	ms_message("x11video_prepare(): Window has size %ix%i, received video is %ix%i",wa.width,wa.height,s->vsize.width,s->vsize.height);

	if (wa.width<MS_LAYOUT_MIN_SIZE || wa.height<MS_LAYOUT_MIN_SIZE){
		return;
	}

	s->wsize.width=wa.width;
	s->wsize.height=wa.height;
	s->fbuf.w=s->vsize.width;
	s->fbuf.h=s->vsize.height;

	s->port=-1;
	if (XvQueryExtension(s->display, &n, &n, &n, &n, &n)!=0){
		ms_error("Fail to query xv extension");
		return;
	}

	if (XShmQueryExtension(s->display)==0){
		ms_error("Fail to query xshm extension");
		return;
	}

	if (XvQueryAdaptors(s->display,DefaultRootWindow(s->display),
	                                 &nadaptors, &xai)!=0){
		ms_error("XvQueryAdaptors failed.");
		return;
	}

	for (n=0;n<nadaptors && port==-1;++n){
		XvAdaptorInfo *ai=&xai[n];
		XvImageFormatValues *imgfmt;
		int nimgfmt=0;

		ms_message("Found output adaptor; name=%s num_ports=%i, with %i formats:",
		           ai->name,(int)ai->num_ports,(int)ai->num_formats);
		imgfmt=XvListImageFormats(s->display,ai->base_id,&nimgfmt);
		for(i=0;i<nimgfmt;++i){
			char fcc[5]={0};
			memcpy(fcc,&imgfmt[i].id,4);
			ms_message("type=%s/%s id=%s",
			           imgfmt[i].type == XvYUV ? "YUV" : "RGB",
			            imgfmt[i].format==XvPlanar ? "Planar" : "Packed",fcc);
			if (port==-1 && imgfmt[i].format==XvPlanar && strcasecmp(fcc,"YV12")==0){
				int k;
				/*we found a format interesting to us*/
				for(k=0;k<ai->num_ports;++k){
					if (XvGrabPort(s->display,ai->base_id+k,CurrentTime)==0){
						ms_message("Grabbed port %i",(int)ai->base_id+k);
						port=ai->base_id+k;
						imgfmt_id=imgfmt[i].id;
						break;
					}
				}
			}
		}
		if (imgfmt) XFree(imgfmt);
	}
	XvFreeAdaptorInfo(xai);
	if (port==-1){
		ms_error("Could not find suitable format or Xv port to work with.");
		return;
	}
	s->port=port;

	/*create the shared memory XvImage*/
	memset(shminfo,0,sizeof(*shminfo));
	s->xv_image=XvShmCreateImage(s->display,s->port,imgfmt_id,NULL,s->fbuf.w,s->fbuf.h,shminfo);
	if (s->xv_image==NULL){
		ms_error("XvShmCreateImage failed.");
		x11video_unprepare(f);
		return;
	}
	/*allocate some shared memory to receive the pixel data */
	shminfo->shmid=shmget(IPC_PRIVATE, s->xv_image->data_size,IPC_CREAT | 0777);
	if (shminfo->shmid==-1){
		ms_error("Could not allocate %i bytes of shared memory: %s",
		         s->xv_image->data_size,
		         strerror(errno));
		x11video_unprepare(f);
		return;
	}
	shminfo->shmaddr=shmat(shminfo->shmid,NULL,0);
	if (shminfo->shmaddr==(void*)-1){
		ms_error("shmat() failed: %s",strerror(errno));
		shminfo->shmaddr=NULL;
		x11video_unprepare(f);
		return;
	}
	/*ask the x-server to attach this shared memory segment*/
	x11_error=FALSE;
	if (!XShmAttach(s->display,shminfo)){
		ms_error("XShmAttach failed !");
		x11video_unprepare(f);
		return ;
	}
	s->xv_image->data=s->shminfo.shmaddr;
	s->fbuf.planes[0]=(void*)s->xv_image->data;
	s->fbuf.planes[2]=s->fbuf.planes[0]+(s->xv_image->height*s->xv_image->pitches[0]);
	s->fbuf.planes[1]=s->fbuf.planes[2]+((s->xv_image->height/2)*s->xv_image->pitches[1]);
	s->fbuf.strides[0]=s->xv_image->pitches[0];
	s->fbuf.strides[2]=s->xv_image->pitches[1];
	s->fbuf.strides[1]=s->xv_image->pitches[2];

	/* set picture black */
	x11video_fill_background(f);

	/*Create a GC*/
	s->gc=XCreateGC(s->display,s->window_id,0,NULL);
	if (s->gc==NULL){
		ms_error("XCreateGC() failed.");
		x11video_unprepare(f);
		return ;
	}

	s->ready=TRUE;
}
Exemplo n.º 28
0
////////////////////////////////////////////////////////////
/// Create the OpenGL rendering context
////////////////////////////////////////////////////////////
bool WindowImplX11::CreateContext(const VideoMode& Mode, XVisualInfo& ChosenVisual, WindowSettings& Params, XVisualInfo Template, unsigned long Mask)
{
    // Get all the visuals matching the template
    Template.screen = ourScreen;
    int NbVisuals = 0;
    XVisualInfo* Visuals = XGetVisualInfo(ourDisplay, Mask | VisualScreenMask, &Template, &NbVisuals);
    if (!Visuals || (NbVisuals == 0))
    {
        if (Visuals)
            XFree(Visuals);
        std::cerr << "There is no valid visual for the selected screen" << std::endl;
        return false;
    }

    // Find the best visual
    int          BestScore  = 0xFFFF;
    XVisualInfo* BestVisual = NULL;
    while (!BestVisual)
    {
        for (int i = 0; i < NbVisuals; ++i)
        {
            // Get the current visual attributes
            int RGBA, DoubleBuffer, Red, Green, Blue, Alpha, Depth, Stencil, MultiSampling, Samples;
            glXGetConfig(ourDisplay, &Visuals[i], GLX_RGBA,               &RGBA);
            glXGetConfig(ourDisplay, &Visuals[i], GLX_DOUBLEBUFFER,       &DoubleBuffer); 
            glXGetConfig(ourDisplay, &Visuals[i], GLX_RED_SIZE,           &Red);
            glXGetConfig(ourDisplay, &Visuals[i], GLX_GREEN_SIZE,         &Green); 
            glXGetConfig(ourDisplay, &Visuals[i], GLX_BLUE_SIZE,          &Blue); 
            glXGetConfig(ourDisplay, &Visuals[i], GLX_ALPHA_SIZE,         &Alpha); 
            glXGetConfig(ourDisplay, &Visuals[i], GLX_DEPTH_SIZE,         &Depth);        
            glXGetConfig(ourDisplay, &Visuals[i], GLX_STENCIL_SIZE,       &Stencil);
            glXGetConfig(ourDisplay, &Visuals[i], GLX_SAMPLE_BUFFERS_ARB, &MultiSampling);        
            glXGetConfig(ourDisplay, &Visuals[i], GLX_SAMPLES_ARB,        &Samples);

            // First check the mandatory parameters
            if ((RGBA == 0) || (DoubleBuffer == 0))
                continue;

            // Evaluate the current configuration
            int Color = Red + Green + Blue + Alpha;
            int Score = EvaluateConfig(Mode, Params, Color, Depth, Stencil, MultiSampling ? Samples : 0);

            // Keep it if it's better than the current best
            if (Score < BestScore)
            {
                BestScore  = Score;
                BestVisual = &Visuals[i];
            }
        }

        // If no visual has been found, try a lower level of antialiasing
        if (!BestVisual)
        {
            if (Params.AntialiasingLevel > 2)
            {
                std::cerr << "Failed to find a pixel format supporting "
                          << Params.AntialiasingLevel << " antialiasing levels ; trying with 2 levels" << std::endl;
                Params.AntialiasingLevel = 2;
            }
            else if (Params.AntialiasingLevel > 0)
            {
                std::cerr << "Failed to find a pixel format supporting antialiasing ; antialiasing will be disabled" << std::endl;
                Params.AntialiasingLevel = 0;
            }
            else
            {
                std::cerr << "Failed to find a suitable pixel format for the window -- cannot create OpenGL context" << std::endl;
                return false;
            }
        }
    }

    // Create the OpenGL context
    myGLContext = glXCreateContext(ourDisplay, BestVisual, glXGetCurrentContext(), true);
    if (myGLContext == NULL)
    {
        std::cerr << "Failed to create an OpenGL context for this window" << std::endl;
        return false;
    }

    // Update the creation settings from the chosen format
    int Depth, Stencil;
    glXGetConfig(ourDisplay, BestVisual, GLX_DEPTH_SIZE,   &Depth);
    glXGetConfig(ourDisplay, BestVisual, GLX_STENCIL_SIZE, &Stencil);
    Params.DepthBits   = static_cast<unsigned int>(Depth);
    Params.StencilBits = static_cast<unsigned int>(Stencil);

    // Assign the chosen visual, and free the temporary visuals array
    ChosenVisual = *BestVisual;
    XFree(Visuals);

    // Activate the context
    SetActive(true);

    // Enable multisampling if needed
    if (Params.AntialiasingLevel > 0)
        glEnable(GL_MULTISAMPLE_ARB);

    return true;
}
Exemplo n.º 29
0
 ~ScreensInfo()
 {
     XFree(m_screens);
 }
Exemplo n.º 30
0
const QRect XfitMan::availableGeometry(int screen) const
{
    QDesktopWidget *d = QApplication::desktop();

    if (screen < 0 || screen >= d->screenCount())
        screen = d->primaryScreen();

    QRect available = d->screenGeometry(screen);

    // Iterate over all the client windows and subtract from the available
    // area the space they reserved on the edges (struts).
    // Note: _NET_WORKAREA is not reliable as it exposes only one
    // rectangular area spanning all screens.
    Display *display = QX11Info::display();
    int x11Screen = d->isVirtualDesktop() ? DefaultScreen(display) : screen;

    Atom ret;
    int format, status;
    uchar* data = 0;
    ulong nitems, after;

    status = XGetWindowProperty(display, QX11Info::appRootWindow(x11Screen),
                                atom("_NET_CLIENT_LIST"), 0L, ~0L, False, XA_WINDOW,
                                &ret, &format, &nitems, &after, &data);

    if (status == Success && ret == XA_WINDOW && format == 32 && nitems)
    {
        const QRect desktopGeometry = d->rect();

        Window* xids = (Window*) data;
        for (quint32 i = 0; i < nitems; ++i)
        {
            ulong nitems2;
            uchar* data2 = 0;
            status = XGetWindowProperty(display, xids[i],
                                        atom("_NET_WM_STRUT_PARTIAL"), 0, 12, False, XA_CARDINAL,
                                        &ret, &format, &nitems2, &after, &data2);

            if (status == Success && ret == XA_CARDINAL && format == 32 && nitems2 == 12)
            {
                ulong* struts = (ulong*) data2;

                QRect left(desktopGeometry.x(),
                           desktopGeometry.y() + struts[4],
                           struts[0],
                           struts[5] - struts[4]);
                if (available.intersects(left))
                    available.setX(left.width());

                QRect right(desktopGeometry.x() + desktopGeometry.width() - struts[1],
                            desktopGeometry.y() + struts[6],
                            struts[1],
                            struts[7] - struts[6]);
                if (available.intersects(right))
                    available.setWidth(right.x() - available.x());

                QRect top(desktopGeometry.x() + struts[8],
                          desktopGeometry.y(),
                          struts[9] - struts[8],
                          struts[2]);
                if (available.intersects(top))
                    available.setY(top.height());

                QRect bottom(desktopGeometry.x() + struts[10],
                             desktopGeometry.y() + desktopGeometry.height() - struts[3],
                             struts[11] - struts[10],
                             struts[3]);
                if (available.intersects(bottom))
                    available.setHeight(bottom.y() - available.y());
            }
            if (data2)
                XFree(data2);
        }
    }
    if (data)
        XFree(data);

    return available;
}