|
@@ -105,15 +105,6 @@ x11GraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
|
|
|
_awaiting_configure = false;
|
|
_awaiting_configure = false;
|
|
|
_dga_mouse_enabled = false;
|
|
_dga_mouse_enabled = false;
|
|
|
_wm_delete_window = x11_pipe->_wm_delete_window;
|
|
_wm_delete_window = x11_pipe->_wm_delete_window;
|
|
|
- _net_wm_window_type = x11_pipe->_net_wm_window_type;
|
|
|
|
|
- _net_wm_window_type_splash = x11_pipe->_net_wm_window_type_splash;
|
|
|
|
|
- _net_wm_window_type_fullscreen = x11_pipe->_net_wm_window_type_fullscreen;
|
|
|
|
|
- _net_wm_state = x11_pipe->_net_wm_state;
|
|
|
|
|
- _net_wm_state_fullscreen = x11_pipe->_net_wm_state_fullscreen;
|
|
|
|
|
- _net_wm_state_above = x11_pipe->_net_wm_state_above;
|
|
|
|
|
- _net_wm_state_below = x11_pipe->_net_wm_state_below;
|
|
|
|
|
- _net_wm_state_add = x11_pipe->_net_wm_state_add;
|
|
|
|
|
- _net_wm_state_remove = x11_pipe->_net_wm_state_remove;
|
|
|
|
|
|
|
|
|
|
GraphicsWindowInputDevice device =
|
|
GraphicsWindowInputDevice device =
|
|
|
GraphicsWindowInputDevice::pointer_and_keyboard(this, "keyboard_mouse");
|
|
GraphicsWindowInputDevice::pointer_and_keyboard(this, "keyboard_mouse");
|
|
@@ -175,7 +166,6 @@ move_pointer(int device, int x, int y) {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
// Function: x11GraphicsWindow::begin_frame
|
|
// Function: x11GraphicsWindow::begin_frame
|
|
|
// Access: Public, Virtual
|
|
// Access: Public, Virtual
|
|
@@ -711,6 +701,88 @@ set_properties_now(WindowProperties &properties) {
|
|
|
properties.clear_foreground();
|
|
properties.clear_foreground();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if (properties.has_mouse_mode()) {
|
|
|
|
|
+ switch (properties.get_mouse_mode()) {
|
|
|
|
|
+ case WindowProperties::M_absolute:
|
|
|
|
|
+ XUngrabPointer(_display, CurrentTime);
|
|
|
|
|
+#ifdef HAVE_XF86DGA
|
|
|
|
|
+ if (_dga_mouse_enabled) {
|
|
|
|
|
+ x11display_cat.info() << "Disabling relative mouse using XF86DGA extension\n";
|
|
|
|
|
+ XF86DGADirectVideo(_display, _screen, 0);
|
|
|
|
|
+ _dga_mouse_enabled = false;
|
|
|
|
|
+ }
|
|
|
|
|
+#endif
|
|
|
|
|
+ _properties.set_mouse_mode(WindowProperties::M_absolute);
|
|
|
|
|
+ properties.clear_mouse_mode();
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ case WindowProperties::M_relative:
|
|
|
|
|
+#ifdef HAVE_XF86DGA
|
|
|
|
|
+ if (!_dga_mouse_enabled) {
|
|
|
|
|
+ int major_ver, minor_ver;
|
|
|
|
|
+ if (XF86DGAQueryVersion(_display, &major_ver, &minor_ver)) {
|
|
|
|
|
+
|
|
|
|
|
+ X11_Cursor cursor = None;
|
|
|
|
|
+ if (_properties.get_cursor_hidden()) {
|
|
|
|
|
+ x11GraphicsPipe *x11_pipe;
|
|
|
|
|
+ DCAST_INTO_V(x11_pipe, _pipe);
|
|
|
|
|
+ cursor = x11_pipe->get_hidden_cursor();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (XGrabPointer(_display, _xwindow, True, 0, GrabModeAsync,
|
|
|
|
|
+ GrabModeAsync, _xwindow, cursor, CurrentTime) != GrabSuccess) {
|
|
|
|
|
+ x11display_cat.error() << "Failed to grab pointer!\n";
|
|
|
|
|
+ } else {
|
|
|
|
|
+ x11display_cat.info() << "Enabling relative mouse using XF86DGA extension\n";
|
|
|
|
|
+ XF86DGADirectVideo(_display, _screen, XF86DGADirectMouse);
|
|
|
|
|
+
|
|
|
|
|
+ _properties.set_mouse_mode(WindowProperties::M_relative);
|
|
|
|
|
+ properties.clear_mouse_mode();
|
|
|
|
|
+ _dga_mouse_enabled = true;
|
|
|
|
|
+
|
|
|
|
|
+ // Get the real mouse position, so we can add/subtract
|
|
|
|
|
+ // our relative coordinates later.
|
|
|
|
|
+ XEvent event;
|
|
|
|
|
+ XQueryPointer(_display, _xwindow, &event.xbutton.root,
|
|
|
|
|
+ &event.xbutton.window, &event.xbutton.x_root, &event.xbutton.y_root,
|
|
|
|
|
+ &event.xbutton.x, &event.xbutton.y, &event.xbutton.state);
|
|
|
|
|
+ _input_devices[0].set_pointer_in_window(event.xbutton.x, event.xbutton.y);
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ x11display_cat.info() << "XF86DGA extension not available\n";
|
|
|
|
|
+ _dga_mouse_enabled = false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+#endif
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ case WindowProperties::M_confined:
|
|
|
|
|
+ {
|
|
|
|
|
+#ifdef HAVE_XF86DGA
|
|
|
|
|
+ if (_dga_mouse_enabled) {
|
|
|
|
|
+ XF86DGADirectVideo(_display, _screen, 0);
|
|
|
|
|
+ _dga_mouse_enabled = false;
|
|
|
|
|
+ }
|
|
|
|
|
+#endif
|
|
|
|
|
+ X11_Cursor cursor = None;
|
|
|
|
|
+ if (_properties.get_cursor_hidden()) {
|
|
|
|
|
+ x11GraphicsPipe *x11_pipe;
|
|
|
|
|
+ DCAST_INTO_V(x11_pipe, _pipe);
|
|
|
|
|
+ cursor = x11_pipe->get_hidden_cursor();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (XGrabPointer(_display, _xwindow, True, 0, GrabModeAsync,
|
|
|
|
|
+ GrabModeAsync, _xwindow, cursor, CurrentTime) != GrabSuccess) {
|
|
|
|
|
+ x11display_cat.error() << "Failed to grab pointer!\n";
|
|
|
|
|
+ } else {
|
|
|
|
|
+ _properties.set_mouse_mode(WindowProperties::M_confined);
|
|
|
|
|
+ properties.clear_mouse_mode();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
set_wm_properties(wm_properties, true);
|
|
set_wm_properties(wm_properties, true);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -721,14 +793,7 @@ set_properties_now(WindowProperties &properties) {
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
void x11GraphicsWindow::
|
|
void x11GraphicsWindow::
|
|
|
mouse_mode_absolute() {
|
|
mouse_mode_absolute() {
|
|
|
-#ifdef HAVE_XF86DGA
|
|
|
|
|
- if (!_dga_mouse_enabled) return;
|
|
|
|
|
-
|
|
|
|
|
- XUngrabPointer(_display, CurrentTime);
|
|
|
|
|
- x11display_cat.info() << "Disabling relative mouse using XF86DGA extension\n";
|
|
|
|
|
- XF86DGADirectVideo(_display, _screen, 0);
|
|
|
|
|
- _dga_mouse_enabled = false;
|
|
|
|
|
-#endif
|
|
|
|
|
|
|
+ // unused: remove in 1.10!
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
@@ -738,42 +803,7 @@ mouse_mode_absolute() {
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
void x11GraphicsWindow::
|
|
void x11GraphicsWindow::
|
|
|
mouse_mode_relative() {
|
|
mouse_mode_relative() {
|
|
|
-#ifdef HAVE_XF86DGA
|
|
|
|
|
- if (_dga_mouse_enabled) return;
|
|
|
|
|
-
|
|
|
|
|
- int major_ver, minor_ver;
|
|
|
|
|
- if (XF86DGAQueryVersion(_display, &major_ver, &minor_ver)) {
|
|
|
|
|
-
|
|
|
|
|
- X11_Cursor cursor = None;
|
|
|
|
|
- if (_properties.get_cursor_hidden()) {
|
|
|
|
|
- x11GraphicsPipe *x11_pipe;
|
|
|
|
|
- DCAST_INTO_V(x11_pipe, _pipe);
|
|
|
|
|
- cursor = x11_pipe->get_hidden_cursor();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (XGrabPointer(_display, _xwindow, True, 0, GrabModeAsync,
|
|
|
|
|
- GrabModeAsync, _xwindow, cursor, CurrentTime) != GrabSuccess) {
|
|
|
|
|
- x11display_cat.error() << "Failed to grab pointer!\n";
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- x11display_cat.info() << "Enabling relative mouse using XF86DGA extension\n";
|
|
|
|
|
- XF86DGADirectVideo(_display, _screen, XF86DGADirectMouse);
|
|
|
|
|
-
|
|
|
|
|
- _dga_mouse_enabled = true;
|
|
|
|
|
- } else {
|
|
|
|
|
- x11display_cat.info() << "XF86DGA extension not available\n";
|
|
|
|
|
- _dga_mouse_enabled = false;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Get the real mouse position, so we can add/subtract
|
|
|
|
|
- // our relative coordinates later.
|
|
|
|
|
- XEvent event;
|
|
|
|
|
- XQueryPointer(_display, _xwindow, &event.xbutton.root,
|
|
|
|
|
- &event.xbutton.window, &event.xbutton.x_root, &event.xbutton.y_root,
|
|
|
|
|
- &event.xbutton.x, &event.xbutton.y, &event.xbutton.state);
|
|
|
|
|
- _input_devices[0].set_pointer_in_window(event.xbutton.x, event.xbutton.y);
|
|
|
|
|
-#endif
|
|
|
|
|
|
|
+ // unused: remove in 1.10!
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
@@ -997,6 +1027,9 @@ open_window() {
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
void x11GraphicsWindow::
|
|
void x11GraphicsWindow::
|
|
|
set_wm_properties(const WindowProperties &properties, bool already_mapped) {
|
|
set_wm_properties(const WindowProperties &properties, bool already_mapped) {
|
|
|
|
|
+ x11GraphicsPipe *x11_pipe;
|
|
|
|
|
+ DCAST_INTO_V(x11_pipe, _pipe);
|
|
|
|
|
+
|
|
|
// Name the window if there is a name
|
|
// Name the window if there is a name
|
|
|
XTextProperty window_name;
|
|
XTextProperty window_name;
|
|
|
XTextProperty *window_name_p = (XTextProperty *)NULL;
|
|
XTextProperty *window_name_p = (XTextProperty *)NULL;
|
|
@@ -1077,15 +1110,15 @@ set_wm_properties(const WindowProperties &properties, bool already_mapped) {
|
|
|
if (properties.get_fullscreen()) {
|
|
if (properties.get_fullscreen()) {
|
|
|
// For a "fullscreen" request, we pass this through, hoping the
|
|
// For a "fullscreen" request, we pass this through, hoping the
|
|
|
// window manager will support EWMH.
|
|
// window manager will support EWMH.
|
|
|
- type_data[next_type_data++] = _net_wm_window_type_fullscreen;
|
|
|
|
|
|
|
+ type_data[next_type_data++] = x11_pipe->_net_wm_window_type_fullscreen;
|
|
|
|
|
|
|
|
// We also request it as a state.
|
|
// We also request it as a state.
|
|
|
- state_data[next_state_data++] = _net_wm_state_fullscreen;
|
|
|
|
|
|
|
+ state_data[next_state_data++] = x11_pipe->_net_wm_state_fullscreen;
|
|
|
// Don't ask me why this has to be 1/0 and not _net_wm_state_add.
|
|
// Don't ask me why this has to be 1/0 and not _net_wm_state_add.
|
|
|
// It doesn't seem to work otherwise.
|
|
// It doesn't seem to work otherwise.
|
|
|
- set_data[next_set_data++] = SetAction(_net_wm_state_fullscreen, 1);
|
|
|
|
|
|
|
+ set_data[next_set_data++] = SetAction(x11_pipe->_net_wm_state_fullscreen, 1);
|
|
|
} else {
|
|
} else {
|
|
|
- set_data[next_set_data++] = SetAction(_net_wm_state_fullscreen, 0);
|
|
|
|
|
|
|
+ set_data[next_set_data++] = SetAction(x11_pipe->_net_wm_state_fullscreen, 0);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// If we asked for a window without a border, there's no excellent
|
|
// If we asked for a window without a border, there's no excellent
|
|
@@ -1112,26 +1145,32 @@ set_wm_properties(const WindowProperties &properties, bool already_mapped) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (properties.get_undecorated() && !properties.get_fullscreen()) {
|
|
if (properties.get_undecorated() && !properties.get_fullscreen()) {
|
|
|
- type_data[next_type_data++] = _net_wm_window_type_splash;
|
|
|
|
|
|
|
+ type_data[next_type_data++] = x11_pipe->_net_wm_window_type_splash;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (properties.has_z_order()) {
|
|
if (properties.has_z_order()) {
|
|
|
switch (properties.get_z_order()) {
|
|
switch (properties.get_z_order()) {
|
|
|
case WindowProperties::Z_bottom:
|
|
case WindowProperties::Z_bottom:
|
|
|
- state_data[next_state_data++] = _net_wm_state_below;
|
|
|
|
|
- set_data[next_set_data++] = SetAction(_net_wm_state_below, _net_wm_state_add);
|
|
|
|
|
- set_data[next_set_data++] = SetAction(_net_wm_state_above, _net_wm_state_remove);
|
|
|
|
|
|
|
+ state_data[next_state_data++] = x11_pipe->_net_wm_state_below;
|
|
|
|
|
+ set_data[next_set_data++] = SetAction(x11_pipe->_net_wm_state_below,
|
|
|
|
|
+ x11_pipe->_net_wm_state_add);
|
|
|
|
|
+ set_data[next_set_data++] = SetAction(x11_pipe->_net_wm_state_above,
|
|
|
|
|
+ x11_pipe->_net_wm_state_remove);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WindowProperties::Z_normal:
|
|
case WindowProperties::Z_normal:
|
|
|
- set_data[next_set_data++] = SetAction(_net_wm_state_below, _net_wm_state_remove);
|
|
|
|
|
- set_data[next_set_data++] = SetAction(_net_wm_state_above, _net_wm_state_remove);
|
|
|
|
|
|
|
+ set_data[next_set_data++] = SetAction(x11_pipe->_net_wm_state_below,
|
|
|
|
|
+ x11_pipe->_net_wm_state_remove);
|
|
|
|
|
+ set_data[next_set_data++] = SetAction(x11_pipe->_net_wm_state_above,
|
|
|
|
|
+ x11_pipe->_net_wm_state_remove);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case WindowProperties::Z_top:
|
|
case WindowProperties::Z_top:
|
|
|
- state_data[next_state_data++] = _net_wm_state_above;
|
|
|
|
|
- set_data[next_set_data++] = SetAction(_net_wm_state_below, _net_wm_state_remove);
|
|
|
|
|
- set_data[next_set_data++] = SetAction(_net_wm_state_above, _net_wm_state_add);
|
|
|
|
|
|
|
+ state_data[next_state_data++] = x11_pipe->_net_wm_state_above;
|
|
|
|
|
+ set_data[next_set_data++] = SetAction(x11_pipe->_net_wm_state_below,
|
|
|
|
|
+ x11_pipe->_net_wm_state_remove);
|
|
|
|
|
+ set_data[next_set_data++] = SetAction(x11_pipe->_net_wm_state_above,
|
|
|
|
|
+ x11_pipe->_net_wm_state_add);
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -1140,12 +1179,18 @@ set_wm_properties(const WindowProperties &properties, bool already_mapped) {
|
|
|
nassertv(next_state_data < max_state_data);
|
|
nassertv(next_state_data < max_state_data);
|
|
|
nassertv(next_set_data < max_set_data);
|
|
nassertv(next_set_data < max_set_data);
|
|
|
|
|
|
|
|
- XChangeProperty(_display, _xwindow, _net_wm_window_type,
|
|
|
|
|
|
|
+ // Add the process ID as a convenience for other applications.
|
|
|
|
|
+ Cardinal pid = getpid();
|
|
|
|
|
+ XChangeProperty(_display, _xwindow, x11_pipe->_net_wm_pid,
|
|
|
|
|
+ XA_CARDINAL, 32, PropModeReplace,
|
|
|
|
|
+ (unsigned char *)&pid, 1);
|
|
|
|
|
+
|
|
|
|
|
+ XChangeProperty(_display, _xwindow, x11_pipe->_net_wm_window_type,
|
|
|
XA_ATOM, 32, PropModeReplace,
|
|
XA_ATOM, 32, PropModeReplace,
|
|
|
(unsigned char *)type_data, next_type_data);
|
|
(unsigned char *)type_data, next_type_data);
|
|
|
|
|
|
|
|
// Request the state properties all at once.
|
|
// Request the state properties all at once.
|
|
|
- XChangeProperty(_display, _xwindow, _net_wm_state,
|
|
|
|
|
|
|
+ XChangeProperty(_display, _xwindow, x11_pipe->_net_wm_state,
|
|
|
XA_ATOM, 32, PropModeReplace,
|
|
XA_ATOM, 32, PropModeReplace,
|
|
|
(unsigned char *)state_data, next_state_data);
|
|
(unsigned char *)state_data, next_state_data);
|
|
|
|
|
|
|
@@ -1164,7 +1209,7 @@ set_wm_properties(const WindowProperties &properties, bool already_mapped) {
|
|
|
event.send_event = True;
|
|
event.send_event = True;
|
|
|
event.display = _display;
|
|
event.display = _display;
|
|
|
event.window = _xwindow;
|
|
event.window = _xwindow;
|
|
|
- event.message_type = _net_wm_state;
|
|
|
|
|
|
|
+ event.message_type = x11_pipe->_net_wm_state;
|
|
|
event.format = 32;
|
|
event.format = 32;
|
|
|
event.data.l[0] = set_data[i]._action;
|
|
event.data.l[0] = set_data[i]._action;
|
|
|
event.data.l[1] = set_data[i]._state;
|
|
event.data.l[1] = set_data[i]._state;
|