From 26a1f66b4e4ba1e13c85448858af03971a3adabb Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 21 Nov 2021 21:22:11 +0900 Subject: [PATCH] [x11] Split up in_x11_init into three stages There's now IN_X11_Preinit, IN_X11_Postinit (both for want of better names), and in_x11_init. The first two are for taking care of initialization that needs to be done before window creation and between window creation and mapping (ie, are very specific to X11 stuff) while in_x11_init takes care of the setup for the input system. This proved necessary in my XInput experimentation: a passive enter grab takes effect only when the pointer enters the window, thus setting up the grab with the pointer already in the window has no effect until the pointer leaves the window and returns. --- include/in_x11.h | 37 ++++++++++++++++++ libs/video/targets/context_x11.c | 6 ++- libs/video/targets/in_x11.c | 66 +++++++++++++++++--------------- 3 files changed, 78 insertions(+), 31 deletions(-) create mode 100644 include/in_x11.h diff --git a/include/in_x11.h b/include/in_x11.h new file mode 100644 index 000000000..a9b83cd77 --- /dev/null +++ b/include/in_x11.h @@ -0,0 +1,37 @@ +/* + in_x11.h + + X11 input handling + + Copyright (C) 2021 Bill Currie + + Author: Bill Currie + Date: 2021/11/21 + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + +*/ + +#ifndef __in_x11_h +#define __in_x11_h + +long IN_X11_Preinit (void); +void IN_X11_Postinit (void); + +#endif//__in_x11_h diff --git a/libs/video/targets/context_x11.c b/libs/video/targets/context_x11.c index b5e8d4050..923203f01 100644 --- a/libs/video/targets/context_x11.c +++ b/libs/video/targets/context_x11.c @@ -68,6 +68,7 @@ #include "context_x11.h" #include "dga_check.h" +#include "in_x11.h" #include "vid_internal.h" static void (*event_handlers[LASTEvent]) (XEvent *); @@ -510,11 +511,14 @@ X11_CreateWindow (int width, int height) if (!attr.colormap) { attr.colormap = XCreateColormap (x_disp, x_root, x_vis, AllocNone); } - attr.event_mask = X11_MASK; + attr.event_mask = X11_MASK | IN_X11_Preinit (); + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; + x_win = XCreateWindow (x_disp, x_root, 0, 0, width, height, 0, x_visinfo->depth, InputOutput, x_vis, mask, &attr); + IN_X11_Postinit (); // Set window size hints SizeHints = XAllocSizeHints (); diff --git a/libs/video/targets/in_x11.c b/libs/video/targets/in_x11.c index e02078464..fb4193d1d 100644 --- a/libs/video/targets/in_x11.c +++ b/libs/video/targets/in_x11.c @@ -78,6 +78,7 @@ #include "compat.h" #include "context_x11.h" #include "dga_check.h" +#include "in_x11.h" #include "qfselect.h" #include "vid_internal.h" @@ -1040,7 +1041,6 @@ in_x11_shutdown (void *data) } if (in_mouse_accel && !in_mouse_accel->int_val) X11_RestoreMouseAcceleration (); - X11_CloseDisplay (); } static void @@ -1081,31 +1081,13 @@ x11_add_device (x11_device_t *dev) dev->devid = IN_AddDevice (x11_driver_handle, dev, dev->name, dev->name); } -static void -in_x11_init (void *data) +long +IN_X11_Preinit (void) { - // open the display if (!x_disp) Sys_Error ("IN: No display!!"); - if (!x_win) - Sys_Error ("IN: No window!!"); - X11_OpenDisplay (); // call to increment the reference counter - - x11_fd = ConnectionNumber (x_disp); - - { - int attribmask = CWEventMask; - - XWindowAttributes attribs_1; - XSetWindowAttributes attribs_2; - - XGetWindowAttributes (x_disp, x_win, &attribs_1); - - attribs_2.event_mask = attribs_1.your_event_mask | X11_INPUT_MASK; - - XChangeWindowAttributes (x_disp, x_win, attribmask, &attribs_2); - } + long event_mask = X11_INPUT_MASK; X11_AddEvent (KeyPress, &event_key); X11_AddEvent (KeyRelease, &event_key); @@ -1114,21 +1096,45 @@ in_x11_init (void *data) X11_AddEvent (SelectionNotify, &selection_notify); X11_AddEvent (EnterNotify, &enter_notify); - x11_add_device (&x11_keyboard_device); - if (!COM_CheckParm ("-nomouse")) { - dga_avail = VID_CheckDGA (x_disp, NULL, NULL, NULL); - Sys_MaskPrintf (SYS_vid, "VID_CheckDGA returned %d\n", dga_avail); - + X11_AddEvent (MotionNotify, &event_motion); X11_AddEvent (ButtonPress, &event_button); X11_AddEvent (ButtonRelease, &event_button); - X11_AddEvent (MotionNotify, &event_motion); - - x11_add_device (&x11_mouse_device); } Cmd_AddCommand ("in_paste_buffer", in_paste_buffer_f, "Paste the contents of X's C&P buffer to the console"); + return event_mask; +} + +void +IN_X11_Postinit (void) +{ + if (!x_disp) + Sys_Error ("IN: No display!!"); + if (!x_win) + Sys_Error ("IN: No window!!"); + + if (!COM_CheckParm ("-nomouse")) { + dga_avail = VID_CheckDGA (x_disp, NULL, NULL, NULL); + Sys_MaskPrintf (SYS_vid, "VID_CheckDGA returned %d\n", dga_avail); + dga_avail = VID_CheckDGA (x_disp, NULL, NULL, NULL); + Sys_MaskPrintf (SYS_vid, "VID_CheckDGA returned %d\n", + dga_avail); + + } +} + +static void +in_x11_init (void *data) +{ + x11_fd = ConnectionNumber (x_disp); + + x11_add_device (&x11_keyboard_device); + + if (!COM_CheckParm ("-nomouse")) { + x11_add_device (&x11_mouse_device); + } } static void