Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDalai Felinto <dfelinto@gmail.com>2015-09-24 18:24:20 +0300
committerDalai Felinto <dfelinto@gmail.com>2015-09-24 18:24:20 +0300
commit27b3ea622f8bd313a8e2827dfec752bf2125566c (patch)
treef212e49d224ce8e1cfc3b17a64ae524711494391 /intern/ghost/intern/GHOST_WindowX11.cpp
parent372dff8d1dc7e24d4b2cd37de245588ecfce8bfa (diff)
parentde80e687689032cb85179a1f7e89750573631d5d (diff)
Merge remote-tracking branch 'origin/master' into cycles_camera_nodescycles_camera_nodes
Note: the branch currently crashes in blender_camera_nodes.cpp: BL::NodeTree b_ntree = b_data.node_groups[nodes_tree_name]; The crash was introduced in: cb7cf523e5c000609f32a382e2c0fcc57f635a42 Conflicts: intern/cycles/SConscript intern/cycles/blender/addon/__init__.py intern/cycles/blender/addon/properties.py intern/cycles/blender/blender_camera.cpp intern/cycles/kernel/kernel_types.h intern/cycles/kernel/svm/svm.h intern/cycles/kernel/svm/svm_types.h intern/cycles/render/camera.cpp intern/cycles/render/camera.h
Diffstat (limited to 'intern/ghost/intern/GHOST_WindowX11.cpp')
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp719
1 files changed, 345 insertions, 374 deletions
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index 86c940b7396..fe99a8bee1e 100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -29,8 +29,10 @@
* \ingroup GHOST
*/
-
-#include <GL/glxew.h>
+/* For standard X11 cursors */
+#include <X11/cursorfont.h>
+#include <X11/Xatom.h>
+#include <X11/Xutil.h>
#include "GHOST_WindowX11.h"
#include "GHOST_SystemX11.h"
@@ -38,20 +40,25 @@
#include "GHOST_Debug.h"
#ifdef WITH_XDND
-#include "GHOST_DropTargetX11.h"
+# include "GHOST_DropTargetX11.h"
#endif
-/* For standard X11 cursors */
-#include <X11/cursorfont.h>
-#include <X11/Xatom.h>
+#if defined(WITH_GL_EGL)
+# include "GHOST_ContextEGL.h"
+#else
+# include "GHOST_ContextGLX.h"
+#endif
#if defined(__sun__) || defined(__sun) || defined(__sparc) || defined(__sparc__) || defined(_AIX)
-#include <strings.h>
+# include <strings.h>
#endif
#include <cstring>
#include <cstdio>
+/* gethostname */
+#include <unistd.h>
+
#include <algorithm>
#include <string>
@@ -65,16 +72,11 @@ typedef struct {
long input_mode;
} MotifWmHints;
-// Workaround for MESA bug #54080
-// https://bugs.freedesktop.org/show_bug.cgi?id=54080()
-#define SWAP_INTERVALS_WORKAROUND
-
-#ifdef SWAP_INTERVALS_WORKAROUND
-static bool g_swap_interval_disabled = false;
-#endif // SWAP_INTERVALS_WORKAROUND
-
#define MWM_HINTS_DECORATIONS (1L << 1)
+#ifndef HOST_NAME_MAX
+# define HOST_NAME_MAX 64
+#endif
// #define GHOST_X11_GRAB
@@ -156,14 +158,79 @@ static long BLENDER_ICON_48x48x32[] = {
4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303,
};
+static XVisualInfo *x11_visualinfo_from_glx(
+ Display *display,
+ bool stereoVisual, GHOST_TUns16 *r_numOfAASamples)
+{
+ XVisualInfo *visualInfo = NULL;
+ GHOST_TUns16 numOfAASamples = *r_numOfAASamples;
+ GHOST_TUns16 actualSamples;
+
+ /* Set up the minimum attributes that we require and see if
+ * X can find us a visual matching those requirements. */
+ int glx_major, glx_minor; /* GLX version: major.minor */
+
+ if (!glXQueryVersion(display, &glx_major, &glx_minor)) {
+ fprintf(stderr,
+ "%s:%d: X11 glXQueryVersion() failed, "
+ "verify working openGL system!\n",
+ __FILE__, __LINE__);
+
+ return NULL;
+ }
+
+ /* GLX >= 1.4 required for multi-sample */
+ if ((glx_major > 1) || (glx_major == 1 && glx_minor >= 4)) {
+ actualSamples = numOfAASamples;
+ }
+ else {
+ numOfAASamples = 0;
+ actualSamples = 0;
+ }
+
+ /* Find the display with highest samples, starting at level requested */
+ for (;;) {
+ int glx_attribs[64];
+
+ GHOST_X11_GL_GetAttributes(glx_attribs, 64, actualSamples, stereoVisual, false);
+
+ visualInfo = glXChooseVisual(display, DefaultScreen(display), glx_attribs);
+
+ /* Any sample level or even zero, which means oversampling disabled, is good
+ * but we need a valid visual to continue */
+ if (visualInfo != NULL) {
+ if (actualSamples < numOfAASamples) {
+ fprintf(stderr,
+ "Warning! Unable to find a multisample pixel format that supports exactly %d samples. "
+ "Substituting one that uses %d samples.\n",
+ numOfAASamples, actualSamples);
+ }
+ break;
+ }
+
+ if (actualSamples == 0) {
+ /* All options exhausted, cannot continue */
+ fprintf(stderr,
+ "%s:%d: X11 glXChooseVisual() failed, "
+ "verify working openGL system!\n",
+ __FILE__, __LINE__);
+
+ return NULL;
+ }
+ else {
+ --actualSamples;
+ }
+ }
+
+ *r_numOfAASamples = actualSamples;
-GLXContext GHOST_WindowX11::s_firstContext = NULL;
+ return visualInfo;
+}
GHOST_WindowX11::
-GHOST_WindowX11(
- GHOST_SystemX11 *system,
+GHOST_WindowX11(GHOST_SystemX11 *system,
Display *display,
- const STR_String& title,
+ const STR_String &title,
GHOST_TInt32 left,
GHOST_TInt32 top,
GHOST_TUns32 width,
@@ -173,109 +240,51 @@ GHOST_WindowX11(
GHOST_TDrawingContextType type,
const bool stereoVisual,
const bool exclusive,
- const GHOST_TUns16 numOfAASamples)
- : GHOST_Window(width, height, state, type, stereoVisual, exclusive, numOfAASamples),
- m_context(NULL),
+ const GHOST_TUns16 numOfAASamples, const bool is_debug)
+ : GHOST_Window(width, height, state, stereoVisual, exclusive, numOfAASamples),
m_display(display),
+ m_visualInfo(NULL),
m_normal_state(GHOST_kWindowStateNormal),
m_system(system),
- m_valid_setup(false),
m_invalid_window(false),
m_empty_cursor(None),
m_custom_cursor(None),
- m_visible_cursor(None)
+ m_visible_cursor(None),
+#ifdef WITH_XDND
+ m_dropTarget(NULL),
+#endif
+#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
+ m_xic(NULL),
+#endif
+ m_valid_setup(false),
+ m_is_debug_context(is_debug)
{
-
- /* Set up the minimum attributes that we require and see if
- * X can find us a visual matching those requirements. */
-
- int attributes[40], i, samples;
- int natom;
- int glxVersionMajor, glxVersionMinor; /* As in GLX major.minor */
-
- m_visual = NULL;
-
- if (!glXQueryVersion(m_display, &glxVersionMajor, &glxVersionMinor)) {
- printf("%s:%d: X11 glXQueryVersion() failed, verify working openGL system!\n", __FILE__, __LINE__);
-
- /* exit if this is the first window */
- if (s_firstContext == NULL) {
- printf("initial window could not find the GLX extension, exit!\n");
- exit(1);
- }
-
- return;
+ if (type == GHOST_kDrawingContextTypeOpenGL) {
+ m_visualInfo = x11_visualinfo_from_glx(m_display, stereoVisual, &m_wantNumOfAASamples);
}
-
- /* Find the display with highest samples, starting at level requested */
- for (samples = m_numOfAASamples; samples >= 0; samples--) {
- i = 0; /* Reusing attributes array, so reset counter */
-
- if (m_stereoVisual)
- attributes[i++] = GLX_STEREO;
-
- attributes[i++] = GLX_RGBA;
- attributes[i++] = GLX_DOUBLEBUFFER;
- attributes[i++] = GLX_RED_SIZE; attributes[i++] = 1;
- attributes[i++] = GLX_BLUE_SIZE; attributes[i++] = 1;
- attributes[i++] = GLX_GREEN_SIZE; attributes[i++] = 1;
- attributes[i++] = GLX_DEPTH_SIZE; attributes[i++] = 1;
-#ifdef GHOST_OPENGL_ALPHA
- attributes[i++] = GLX_ALPHA_SIZE; attributes[i++] = 1;
-#endif
- /* GLX >= 1.4 required for multi-sample */
- if (samples && (glxVersionMajor >= 1) && (glxVersionMinor >= 4)) {
- attributes[i++] = GLX_SAMPLE_BUFFERS; attributes[i++] = 1;
- attributes[i++] = GLX_SAMPLES; attributes[i++] = samples;
- }
- attributes[i] = None;
-
- m_visual = glXChooseVisual(m_display, DefaultScreen(m_display), attributes);
-
- /* Any sample level or even zero, which means oversampling disabled, is good
- * but we need a valid visual to continue */
- if (m_visual == NULL) {
- if (samples == 0) {
- /* All options exhausted, cannot continue */
- printf("%s:%d: X11 glXChooseVisual() failed, verify working openGL system!\n", __FILE__, __LINE__);
-
- if (s_firstContext == NULL) {
- printf("initial window could not find the GLX extension, exit!\n");
- exit(1);
- }
-
- return;
- }
- }
- else {
- if (m_numOfAASamples && (m_numOfAASamples > samples)) {
- printf("%s:%d: oversampling requested %i but using %i samples\n",
- __FILE__, __LINE__, m_numOfAASamples, samples);
- }
- break;
- }
+ else {
+ XVisualInfo tmp = {0};
+ int n;
+ m_visualInfo = XGetVisualInfo(m_display, 0, &tmp, &n);
}
- /* Create a bunch of attributes needed to create an X window. */
-
+ /* caller needs to check 'getValid()' */
+ if (m_visualInfo == NULL) {
+ fprintf(stderr, "initial window could not find the GLX extension\n");
+ return;
+ }
- /* First create a colormap for the window and visual.
- * This seems pretty much a legacy feature as we are in rgba mode anyway. */
+ unsigned int xattributes_valuemask = 0;
XSetWindowAttributes xattributes;
- unsigned int xattributes_valuemask = (CWBorderPixel | CWColormap | CWEventMask);
memset(&xattributes, 0, sizeof(xattributes));
- xattributes.colormap = XCreateColormap(m_display,
- RootWindow(m_display, m_visual->screen),
- m_visual->visual,
- AllocNone
- );
-
+ xattributes_valuemask |= CWBorderPixel;
xattributes.border_pixel = 0;
/* Specify which events we are interested in hearing. */
+ xattributes_valuemask |= CWEventMask;
xattributes.event_mask =
ExposureMask | StructureNotifyMask |
KeyPressMask | KeyReleaseMask |
@@ -289,24 +298,28 @@ GHOST_WindowX11(
xattributes.override_redirect = True;
}
+ xattributes_valuemask |= CWColormap;
+ xattributes.colormap = XCreateColormap(
+ m_display,
+ RootWindow(m_display, m_visualInfo->screen),
+ m_visualInfo->visual,
+ AllocNone
+ );
+
/* create the window! */
if (parentWindow == 0) {
- m_window = XCreateWindow(m_display,
- RootWindow(m_display, m_visual->screen),
- left,
- top,
- width,
- height,
- 0, /* no border. */
- m_visual->depth,
- InputOutput,
- m_visual->visual,
- xattributes_valuemask,
- &xattributes
- );
+ m_window = XCreateWindow(
+ m_display,
+ RootWindow(m_display, m_visualInfo->screen),
+ left, top, width, height,
+ 0, /* no border. */
+ m_visualInfo->depth,
+ InputOutput,
+ m_visualInfo->visual,
+ xattributes_valuemask,
+ &xattributes);
}
else {
-
Window root_return;
int x_return, y_return;
unsigned int w_return, h_return, border_w_return, depth_return;
@@ -320,19 +333,16 @@ GHOST_WindowX11(
height = h_return;
- m_window = XCreateWindow(m_display,
- parentWindow, /* reparent against embedder */
- left,
- top,
- width,
- height,
- 0, /* no border. */
- m_visual->depth,
- InputOutput,
- m_visual->visual,
- xattributes_valuemask,
- &xattributes
- );
+ m_window = XCreateWindow(
+ m_display,
+ parentWindow, /* reparent against embedder */
+ left, top, width, height,
+ 0, /* no border. */
+ m_visualInfo->depth,
+ InputOutput,
+ m_visualInfo->visual,
+ xattributes_valuemask,
+ &xattributes);
XSelectInput(m_display, parentWindow, SubstructureNotifyMask);
@@ -384,36 +394,43 @@ GHOST_WindowX11(
m_post_state = GHOST_kWindowStateNormal;
}
+
/* Create some hints for the window manager on how
* we want this window treated. */
+ {
+ XSizeHints *xsizehints = XAllocSizeHints();
+ xsizehints->flags = PPosition | PSize | PMinSize | PMaxSize;
+ xsizehints->x = left;
+ xsizehints->y = top;
+ xsizehints->width = width;
+ xsizehints->height = height;
+ xsizehints->min_width = 320; /* size hints, could be made apart of the ghost api */
+ xsizehints->min_height = 240; /* limits are also arbitrary, but should not allow 1x1 window */
+ xsizehints->max_width = 65535;
+ xsizehints->max_height = 65535;
+ XSetWMNormalHints(m_display, m_window, xsizehints);
+ XFree(xsizehints);
+ }
+
+
+ /* XClassHint, title */
+ {
+ XClassHint *xclasshint = XAllocClassHint();
+ const int len = title.Length() + 1;
+ char *wmclass = (char *)malloc(sizeof(char) * len);
+ memcpy(wmclass, title.ReadPtr(), len * sizeof(char));
+ xclasshint->res_name = wmclass;
+ xclasshint->res_class = wmclass;
+ XSetClassHint(m_display, m_window, xclasshint);
+ free(wmclass);
+ XFree(xclasshint);
+ }
- XSizeHints *xsizehints = XAllocSizeHints();
- xsizehints->flags = PPosition | PSize | PMinSize | PMaxSize;
- xsizehints->x = left;
- xsizehints->y = top;
- xsizehints->width = width;
- xsizehints->height = height;
- xsizehints->min_width = 320; /* size hints, could be made apart of the ghost api */
- xsizehints->min_height = 240; /* limits are also arbitrary, but should not allow 1x1 window */
- xsizehints->max_width = 65535;
- xsizehints->max_height = 65535;
- XSetWMNormalHints(m_display, m_window, xsizehints);
- XFree(xsizehints);
-
- XClassHint *xclasshint = XAllocClassHint();
- const int len = title.Length() + 1;
- char *wmclass = (char *)malloc(sizeof(char) * len);
- strncpy(wmclass, (const char *)title, sizeof(char) * len);
- xclasshint->res_name = wmclass;
- xclasshint->res_class = wmclass;
- XSetClassHint(m_display, m_window, xclasshint);
- free(wmclass);
- XFree(xclasshint);
/* The basic for a good ICCCM "work" */
if (m_system->m_atom.WM_PROTOCOLS) {
Atom atoms[2];
- natom = 0;
+ int natom = 0;
if (m_system->m_atom.WM_DELETE_WINDOW) {
atoms[natom] = m_system->m_atom.WM_DELETE_WINDOW;
@@ -431,27 +448,48 @@ GHOST_WindowX11(
}
}
-#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
- m_xic = NULL;
-#endif
-
/* Set the window hints */
- XWMHints *xwmhints = XAllocWMHints();
- xwmhints->initial_state = NormalState;
- xwmhints->input = True;
- xwmhints->flags = InputHint | StateHint;
- XSetWMHints(display, m_window, xwmhints);
- XFree(xwmhints);
- /* done setting the hints */
+ {
+ XWMHints *xwmhints = XAllocWMHints();
+ xwmhints->initial_state = NormalState;
+ xwmhints->input = True;
+ xwmhints->flags = InputHint | StateHint;
+ XSetWMHints(display, m_window, xwmhints);
+ XFree(xwmhints);
+ }
+
/* set the icon */
- Atom _NET_WM_ICON = XInternAtom(m_display, "_NET_WM_ICON", False);
- XChangeProperty(m_display, m_window, _NET_WM_ICON, XA_CARDINAL,
- 32, PropModeReplace, (unsigned char *)BLENDER_ICON_48x48x32,
- BLENDER_ICON_48x48x32[0] * BLENDER_ICON_48x48x32[1] + 2);
- /* done setting the icon */
+ {
+ Atom _NET_WM_ICON = XInternAtom(m_display, "_NET_WM_ICON", False);
+ XChangeProperty(m_display, m_window, _NET_WM_ICON, XA_CARDINAL,
+ 32, PropModeReplace, (unsigned char *)BLENDER_ICON_48x48x32,
+ BLENDER_ICON_48x48x32[0] * BLENDER_ICON_48x48x32[1] + 2);
+ }
- setTitle(title);
+ /* set the process ID (_NET_WM_PID) */
+ {
+ Atom _NET_WM_PID = XInternAtom(m_display, "_NET_WM_PID", False);
+ pid_t pid = getpid();
+ XChangeProperty(m_display, m_window, _NET_WM_PID, XA_CARDINAL,
+ 32, PropModeReplace, (unsigned char *)&pid, 1);
+ }
+
+
+ /* set the hostname (WM_CLIENT_MACHINE) */
+ {
+ char hostname[HOST_NAME_MAX];
+ char *text_array[1];
+ XTextProperty text_prop;
+
+ gethostname(hostname, sizeof(hostname));
+ hostname[sizeof(hostname) - 1] = '\0';
+ text_array[0] = hostname;
+
+ XStringListToTextProperty(text_array, 1, &text_prop);
+ XSetWMClientMachine(m_display, m_window, &text_prop);
+ XFree(text_prop.value);
+ }
#ifdef WITH_X11_XINPUT
initXInputDevices();
@@ -459,12 +497,15 @@ GHOST_WindowX11(
m_tabletData.Active = GHOST_kTabletModeNone;
#endif
+
/* now set up the rendering context. */
- if (installDrawingContext(type) == GHOST_kSuccess) {
+ if (setDrawingContextType(type) == GHOST_kSuccess) {
m_valid_setup = true;
GHOST_PRINT("Created window\n");
}
+ setTitle(title);
+
if (exclusive) {
XMapRaised(m_display, m_window);
}
@@ -477,7 +518,7 @@ GHOST_WindowX11(
}
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
-static void destroyICCallback(XIC xic, XPointer ptr, XPointer data)
+static void destroyICCallback(XIC /*xic*/, XPointer ptr, XPointer /*data*/)
{
GHOST_PRINT("XIM input context destroyed\n");
@@ -525,23 +566,32 @@ void GHOST_WindowX11::initXInputDevices()
if (version && (version != (XExtensionVersion *)NoSuchExtension)) {
if (version->present) {
GHOST_SystemX11::GHOST_TabletX11 &xtablet = m_system->GetXTablet();
- XEventClass xevents[10], ev;
+ XEventClass xevents[8], ev;
int dcount = 0;
+ /* With modern XInput (xlib 1.6.2 at least and/or evdev 2.9.0) and some 'no-name' tablets
+ * like 'UC-LOGIC Tablet WP5540U', we also need to 'select' ButtonPress for motion event,
+ * otherwise we do not get any tablet motion event once pen is pressed... See T43367.
+ */
+
if (xtablet.StylusDevice) {
DeviceMotionNotify(xtablet.StylusDevice, xtablet.MotionEvent, ev);
if (ev) xevents[dcount++] = ev;
+ DeviceButtonPress(xtablet.StylusDevice, xtablet.PressEvent, ev);
+ if (ev) xevents[dcount++] = ev;
ProximityIn(xtablet.StylusDevice, xtablet.ProxInEvent, ev);
if (ev) xevents[dcount++] = ev;
ProximityOut(xtablet.StylusDevice, xtablet.ProxOutEvent, ev);
if (ev) xevents[dcount++] = ev;
}
if (xtablet.EraserDevice) {
- DeviceMotionNotify(xtablet.EraserDevice, xtablet.MotionEvent, ev);
+ DeviceMotionNotify(xtablet.EraserDevice, xtablet.MotionEventEraser, ev);
if (ev) xevents[dcount++] = ev;
- ProximityIn(xtablet.EraserDevice, xtablet.ProxInEvent, ev);
+ DeviceButtonPress(xtablet.EraserDevice, xtablet.PressEventEraser, ev);
if (ev) xevents[dcount++] = ev;
- ProximityOut(xtablet.EraserDevice, xtablet.ProxOutEvent, ev);
+ ProximityIn(xtablet.EraserDevice, xtablet.ProxInEventEraser, ev);
+ if (ev) xevents[dcount++] = ev;
+ ProximityOut(xtablet.EraserDevice, xtablet.ProxOutEventEraser, ev);
if (ev) xevents[dcount++] = ev;
}
@@ -564,7 +614,7 @@ bool
GHOST_WindowX11::
getValid() const
{
- return m_valid_setup;
+ return GHOST_Window::getValid() && m_valid_setup;
}
void
@@ -685,7 +735,7 @@ screenToClient(
Window temp;
XTranslateCoordinates(m_display,
- RootWindow(m_display, m_visual->screen),
+ RootWindow(m_display, m_visualInfo->screen),
m_window,
inX, inY,
&ax, &ay,
@@ -708,7 +758,7 @@ clientToScreen(
XTranslateCoordinates(
m_display,
m_window,
- RootWindow(m_display, m_visual->screen),
+ RootWindow(m_display, m_visualInfo->screen),
inX, inY,
&ax, &ay,
&temp);
@@ -731,7 +781,7 @@ void GHOST_WindowX11::icccmSetState(int state)
xev.xclient.format = 32;
xev.xclient.message_type = m_system->m_atom.WM_CHANGE_STATE;
xev.xclient.data.l[0] = state;
- XSendEvent(m_display, RootWindow(m_display, DefaultScreen(m_display)),
+ XSendEvent(m_display, RootWindow(m_display, m_visualInfo->screen),
False, SubstructureNotifyMask | SubstructureRedirectMask, &xev);
}
@@ -777,7 +827,7 @@ void GHOST_WindowX11::netwmMaximized(bool set)
xev.xclient.data.l[2] = m_system->m_atom._NET_WM_STATE_MAXIMIZED_VERT;
xev.xclient.data.l[3] = 0;
xev.xclient.data.l[4] = 0;
- XSendEvent(m_display, RootWindow(m_display, DefaultScreen(m_display)),
+ XSendEvent(m_display, RootWindow(m_display, m_visualInfo->screen),
False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
}
@@ -833,7 +883,7 @@ void GHOST_WindowX11::netwmFullScreen(bool set)
xev.xclient.data.l[2] = 0;
xev.xclient.data.l[3] = 0;
xev.xclient.data.l[4] = 0;
- XSendEvent(m_display, RootWindow(m_display, DefaultScreen(m_display)),
+ XSendEvent(m_display, RootWindow(m_display, m_visualInfo->screen),
False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
}
@@ -1052,7 +1102,7 @@ setOrder(
xev.xclient.data.l[3] = 0;
xev.xclient.data.l[4] = 0;
- root = RootWindow(m_display, m_visual->screen),
+ root = RootWindow(m_display, m_visualInfo->screen),
eventmask = SubstructureRedirectMask | SubstructureNotifyMask;
XSendEvent(m_display, root, False, eventmask, &xev);
@@ -1079,34 +1129,6 @@ setOrder(
GHOST_TSuccess
GHOST_WindowX11::
-swapBuffers()
-{
- if (getDrawingContextType() == GHOST_kDrawingContextTypeOpenGL) {
- glXSwapBuffers(m_display, m_window);
- return GHOST_kSuccess;
- }
- else {
- return GHOST_kFailure;
- }
-}
-
-GHOST_TSuccess
-GHOST_WindowX11::
-activateDrawingContext()
-{
- if (m_context != NULL) {
- glXMakeCurrent(m_display, m_window, m_context);
- /* Disable AA by default */
- if (m_numOfAASamples > 0) {
- glDisable(GL_MULTISAMPLE_ARB);
- }
- return GHOST_kSuccess;
- }
- return GHOST_kFailure;
-}
-
-GHOST_TSuccess
-GHOST_WindowX11::
invalidate()
{
/* So the idea of this function is to generate an expose event
@@ -1151,15 +1173,6 @@ validate()
GHOST_WindowX11::
~GHOST_WindowX11()
{
- static Atom Primary_atom, Clipboard_atom;
- Window p_owner, c_owner;
- /*Change the owner of the Atoms to None if we are the owner*/
- Primary_atom = XInternAtom(m_display, "PRIMARY", False);
- Clipboard_atom = XInternAtom(m_display, "CLIPBOARD", False);
-
- p_owner = XGetSelectionOwner(m_display, Primary_atom);
- c_owner = XGetSelectionOwner(m_display, Clipboard_atom);
-
std::map<unsigned int, Cursor>::iterator it = m_standard_cursors.begin();
for (; it != m_standard_cursors.end(); ++it) {
XFreeCursor(m_display, it->second);
@@ -1172,17 +1185,29 @@ GHOST_WindowX11::
XFreeCursor(m_display, m_custom_cursor);
}
- if (m_context != s_firstContext) {
- glXDestroyContext(m_display, m_context);
+ if (m_valid_setup) {
+ static Atom Primary_atom, Clipboard_atom;
+ Window p_owner, c_owner;
+ /*Change the owner of the Atoms to None if we are the owner*/
+ Primary_atom = XInternAtom(m_display, "PRIMARY", False);
+ Clipboard_atom = XInternAtom(m_display, "CLIPBOARD", False);
+
+
+ p_owner = XGetSelectionOwner(m_display, Primary_atom);
+ c_owner = XGetSelectionOwner(m_display, Clipboard_atom);
+
+ if (p_owner == m_window) {
+ XSetSelectionOwner(m_display, Primary_atom, None, CurrentTime);
+ }
+ if (c_owner == m_window) {
+ XSetSelectionOwner(m_display, Clipboard_atom, None, CurrentTime);
+ }
}
- if (p_owner == m_window) {
- XSetSelectionOwner(m_display, Primary_atom, None, CurrentTime);
- }
- if (c_owner == m_window) {
- XSetSelectionOwner(m_display, Clipboard_atom, None, CurrentTime);
+ if (m_visualInfo) {
+ XFree(m_visualInfo);
}
-
+
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
if (m_xic) {
XDestroyIC(m_xic);
@@ -1193,88 +1218,103 @@ GHOST_WindowX11::
delete m_dropTarget;
#endif
- XDestroyWindow(m_display, m_window);
- XFree(m_visual);
-}
-
+ releaseNativeHandles();
+ if (m_valid_setup) {
+ XDestroyWindow(m_display, m_window);
+ }
+}
-/**
- * Tries to install a rendering context in this window.
- * \param type The type of rendering context installed.
- * \return Indication as to whether installation has succeeded.
- */
-GHOST_TSuccess
-GHOST_WindowX11::
-installDrawingContext(
- GHOST_TDrawingContextType type)
+GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type)
{
- /* only support openGL for now. */
- GHOST_TSuccess success;
- switch (type) {
- case GHOST_kDrawingContextTypeOpenGL:
- {
-#ifdef WITH_X11_XINPUT
- /* use our own event handlers to avoid exiting blender,
- * this would happen for eg:
- * if you open blender, unplug a tablet, then open a new window. */
- XErrorHandler old_handler = XSetErrorHandler(GHOST_X11_ApplicationErrorHandler);
- XIOErrorHandler old_handler_io = XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler);
+ if (type == GHOST_kDrawingContextTypeOpenGL) {
+#if !defined(WITH_GL_EGL)
+
+#if defined(WITH_GL_PROFILE_CORE)
+ GHOST_Context *context = new GHOST_ContextGLX(
+ m_wantStereoVisual,
+ m_wantNumOfAASamples,
+ m_window,
+ m_display,
+ m_visualInfo,
+ GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
+ 3, 2,
+ GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
+ GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
+#elif defined(WITH_GL_PROFILE_ES20)
+ GHOST_Context *context = new GHOST_ContextGLX(
+ m_wantStereoVisual,
+ m_wantNumOfAASamples,
+ m_window,
+ m_display,
+ m_visualInfo,
+ GLX_CONTEXT_ES2_PROFILE_BIT_EXT,
+ 2, 0,
+ GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
+ GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
+#elif defined(WITH_GL_PROFILE_COMPAT)
+ GHOST_Context *context = new GHOST_ContextGLX(
+ m_wantStereoVisual,
+ m_wantNumOfAASamples,
+ m_window,
+ m_display,
+ m_visualInfo,
+ 0, // profile bit
+ 0, 0,
+ GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
+ GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
+#else
+# error
#endif
- m_context = glXCreateContext(m_display, m_visual, s_firstContext, True);
- if (m_context != NULL) {
- if (!s_firstContext) {
- s_firstContext = m_context;
- }
- glXMakeCurrent(m_display, m_window, m_context);
- glClearColor(0.447, 0.447, 0.447, 0);
- glClear(GL_COLOR_BUFFER_BIT);
- success = GHOST_kSuccess;
- }
- else {
- success = GHOST_kFailure;
- }
+#else
+
+#if defined(WITH_GL_PROFILE_CORE)
+ GHOST_Context *context = new GHOST_ContextEGL(
+ m_wantStereoVisual,
+ m_wantNumOfAASamples,
+ m_window,
+ m_display,
+ EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
+ 3, 2,
+ GHOST_OPENGL_EGL_CONTEXT_FLAGS,
+ GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
+ EGL_OPENGL_API);
+#elif defined(WITH_GL_PROFILE_ES20)
+ GHOST_Context *context = new GHOST_ContextEGL(
+ m_wantStereoVisual,
+ m_wantNumOfAASamples,
+ m_window,
+ m_display,
+ 0, // profile bit
+ 2, 0,
+ GHOST_OPENGL_EGL_CONTEXT_FLAGS,
+ GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
+ EGL_OPENGL_ES_API);
+#elif defined(WITH_GL_PROFILE_COMPAT)
+ GHOST_Context *context = new GHOST_ContextEGL(
+ m_wantStereoVisual,
+ m_wantNumOfAASamples,
+ m_window,
+ m_display,
+ 0, // profile bit
+ 0, 0,
+ GHOST_OPENGL_EGL_CONTEXT_FLAGS,
+ GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
+ EGL_OPENGL_API);
+#else
+# error
+#endif
-#ifdef WITH_X11_XINPUT
- /* Restore handler */
- (void) XSetErrorHandler(old_handler);
- (void) XSetIOErrorHandler(old_handler_io);
#endif
- break;
- }
- case GHOST_kDrawingContextTypeNone:
- {
- success = GHOST_kSuccess;
- break;
- }
- default:
- success = GHOST_kFailure;
+ if (context->initializeDrawingContext())
+ return context;
+ else
+ delete context;
}
- return success;
-}
-
-
-
-/**
- * Removes the current drawing context.
- * \return Indication as to whether removal has succeeded.
- */
-GHOST_TSuccess
-GHOST_WindowX11::
-removeDrawingContext()
-{
- GHOST_TSuccess success;
- if (m_context != NULL) {
- glXDestroyContext(m_display, m_context);
- success = GHOST_kSuccess;
- }
- else {
- success = GHOST_kFailure;
- }
- return success;
+ return NULL;
}
@@ -1336,13 +1376,13 @@ getEmptyCursor(
) {
if (!m_empty_cursor) {
Pixmap blank;
- XColor dummy;
+ XColor dummy = {0};
char data[1] = {0};
/* make a blank cursor */
blank = XCreateBitmapFromData(
m_display,
- RootWindow(m_display, DefaultScreen(m_display)),
+ RootWindow(m_display, m_visualInfo->screen),
data, 1, 1
);
@@ -1458,10 +1498,10 @@ setWindowCustomCursorShape(
int sizey,
int hotX,
int hotY,
- int fg_color,
- int bg_color)
+ int /*fg_color*/,
+ int /*bg_color*/)
{
- Colormap colormap = DefaultColormap(m_display, DefaultScreen(m_display));
+ Colormap colormap = DefaultColormap(m_display, m_visualInfo->screen);
Pixmap bitmap_pix, mask_pix;
XColor fg, bg;
@@ -1530,72 +1570,3 @@ endFullScreen() const
return GHOST_kSuccess;
}
-
-GHOST_TSuccess
-GHOST_WindowX11::
-setSwapInterval(int interval) {
- if (!GLX_EXT_swap_control || !glXSwapIntervalEXT
-#ifdef SWAP_INTERVALS_WORKAROUND
- || g_swap_interval_disabled
-#endif // SWAP_INTERVALS_WORKAROUND
- )
- {
- return GHOST_kFailure;
- }
- glXSwapIntervalEXT(m_display, m_window, interval);
- return GHOST_kSuccess;
-}
-
-#ifdef SWAP_INTERVALS_WORKAROUND
-static int QueryDrawable_ApplicationErrorHandler(Display *display, XErrorEvent *theEvent)
-{
- fprintf(stderr, "Ignoring Xlib error: error code %d request code %d\n",
- theEvent->error_code, theEvent->request_code);
- if (!g_swap_interval_disabled) {
- fprintf(stderr, "Disabling SWAP INTERVALS extension\n");
- g_swap_interval_disabled = true;
- }
- return 0;
-}
-
-static int QueryDrawable_ApplicationIOErrorHandler(Display *display)
-{
- fprintf(stderr, "Ignoring Xlib error: error IO\n");
- if (!g_swap_interval_disabled) {
- fprintf(stderr, "Disabling SWAP INTERVALS extension\n");
- g_swap_interval_disabled = true;
- }
- return 0;
-}
-#endif // SWAP_INTERVALS_WORKAROUND
-
-int
-GHOST_WindowX11::
-getSwapInterval() {
- if (GLX_EXT_swap_control) {
-#ifdef SWAP_INTERVALS_WORKAROUND
- /* XXX: Current MESA driver will give GLXBadDrawable for all
- * the glXQueryDrawable requests with direct contexts.
- *
- * To prevent crashes and unexpected behaviors, we will
- * disable swap intervals extension if query fails here.
- * (because if we will override interval without having
- * old value we couldn't restore it properly).
- */
- XErrorHandler old_handler = XSetErrorHandler(QueryDrawable_ApplicationErrorHandler);
- XIOErrorHandler old_handler_io = XSetIOErrorHandler(QueryDrawable_ApplicationIOErrorHandler);
-#endif // SWAP_INTERVALS_WORKAROUND
-
- unsigned int value = 0;
- glXQueryDrawable(m_display, m_window, GLX_SWAP_INTERVAL_EXT, &value);
-
-#ifdef SWAP_INTERVALS_WORKAROUND
- /* Restore handler */
- (void) XSetErrorHandler(old_handler);
- (void) XSetIOErrorHandler(old_handler_io);
-#endif // SWAP_INTERVALS_WORKAROUND
-
- return (int)value;
- }
- return 0;
-}