* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
GdkScreen *screen,
gint x,
gint y);
-static gboolean gdk_broadway_device_query_state (GdkDevice *device,
- GdkWindow *window,
- GdkWindow **root_window,
- GdkWindow **child_window,
- gint *root_x,
- gint *root_y,
- gint *win_x,
- gint *win_y,
- GdkModifierType *mask);
+static void gdk_broadway_device_query_state (GdkDevice *device,
+ GdkWindow *window,
+ GdkWindow **root_window,
+ GdkWindow **child_window,
+ gint *root_x,
+ gint *root_y,
+ gint *win_x,
+ gint *win_y,
+ GdkModifierType *mask);
static GdkGrabStatus gdk_broadway_device_grab (GdkDevice *device,
GdkWindow *window,
gboolean owner_events,
{
}
-static gboolean
+static void
gdk_broadway_device_query_state (GdkDevice *device,
GdkWindow *window,
GdkWindow **root_window,
gint *win_y,
GdkModifierType *mask)
{
+ GdkWindow *toplevel;
+ GdkWindowImplBroadway *impl;
GdkDisplay *display;
GdkBroadwayDisplay *broadway_display;
- GdkWindowImplBroadway *impl;
- guint32 serial;
GdkScreen *screen;
- char *reply;
- gint device_root_x, device_root_y, device_win_x, device_win_y, id;
+ gint32 device_root_x, device_root_y;
+ guint32 mouse_toplevel_id;
+ GdkWindow *mouse_toplevel;
+ guint32 mask32;
if (gdk_device_get_source (device) != GDK_SOURCE_MOUSE)
- return FALSE;
+ return;
display = gdk_device_get_display (device);
broadway_display = GDK_BROADWAY_DISPLAY (display);
+ impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
+ toplevel = impl->wrapper;
+
if (root_window)
{
screen = gdk_window_get_screen (window);
*root_window = gdk_screen_get_root_window (screen);
}
- if (mask)
- *mask = 0; /* TODO */
-
- if (broadway_display->output)
- {
- impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
-
- serial = broadway_output_query_pointer (broadway_display->output, impl->id);
-
- reply = _gdk_broadway_display_block_for_input (display, 'q', serial);
-
- if (reply != NULL)
- {
- char *p;
- char cmd;
- guint32 reply_serial;
-
- p = reply;
-
- cmd = *p++;
- reply_serial = (guint32)strtol(p, &p, 10);
- p++; /* Skip , */
-
- device_root_x = strtol(p, &p, 10);
- p++; /* Skip , */
- device_root_y = strtol(p, &p, 10);
- p++; /* Skip , */
- device_win_x = strtol(p, &p, 10);
- p++; /* Skip , */
- device_win_y = strtol(p, &p, 10);
- p++; /* Skip , */
- id = strtol(p, &p, 10);
-
- if (root_x)
- *root_x = device_root_x;
- if (root_y)
- *root_y = device_root_y;
- if (win_x)
- *win_x = device_win_x;
- if (win_y)
- *win_y = device_win_y;
- if (child_window)
- {
- if (gdk_window_get_window_type (window) == GDK_WINDOW_ROOT)
- *child_window = g_hash_table_lookup (broadway_display->id_ht, GINT_TO_POINTER (id));
- else
- *child_window = window; /* No native children */
- }
- g_free (reply);
- return TRUE;
- }
- }
-
- /* Fallback when unconnected */
-
- device_root_x = broadway_display->last_x;
- device_root_y = broadway_display->last_y;
+ _gdk_broadway_server_query_mouse (broadway_display->server,
+ &mouse_toplevel_id,
+ &device_root_x,
+ &device_root_y,
+ &mask32);
+ mouse_toplevel = g_hash_table_lookup (broadway_display->id_ht, GUINT_TO_POINTER (mouse_toplevel_id));
if (root_x)
*root_x = device_root_x;
if (root_y)
*root_y = device_root_y;
if (win_x)
- *win_x = device_root_y - window->x;
+ *win_x = device_root_y - toplevel->x;
if (win_y)
- *win_y = device_root_y - window->y;
+ *win_y = device_root_y - toplevel->y;
+ if (mask)
+ *mask = mask32;
if (child_window)
{
- if (gdk_window_get_window_type (window) == GDK_WINDOW_ROOT)
+ if (gdk_window_get_window_type (toplevel) == GDK_WINDOW_ROOT)
{
- *child_window = broadway_display->mouse_in_toplevel;
+ *child_window = mouse_toplevel;
if (*child_window == NULL)
- *child_window = window;
+ *child_window = toplevel;
}
else
{
/* No native children */
- *child_window = window;
+ *child_window = toplevel;
}
}
- return TRUE;
+ return;
+}
+
+void
+_gdk_broadway_window_grab_check_destroy (GdkWindow *window)
+{
+ GdkDisplay *display = gdk_window_get_display (window);
+ GdkDeviceManager *device_manager;
+ GdkDeviceGrabInfo *grab;
+ GList *devices, *d;
+
+ device_manager = gdk_display_get_device_manager (display);
+
+ /* Get all devices */
+ devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
+
+ for (d = devices; d; d = d->next)
+ {
+ /* Make sure there is no lasting grab in this native window */
+ grab = _gdk_display_get_last_device_grab (display, d->data);
+
+ if (grab && grab->native_window == window)
+ {
+ grab->serial_end = grab->serial_start;
+ grab->implicit_ungrab = TRUE;
+ }
+
+ }
+
+ g_list_free (devices);
}
+
static GdkGrabStatus
gdk_broadway_device_grab (GdkDevice *device,
GdkWindow *window,
GdkCursor *cursor,
guint32 time_)
{
- return GDK_GRAB_NOT_VIEWABLE;
+ GdkDisplay *display;
+ GdkBroadwayDisplay *broadway_display;
+
+ display = gdk_device_get_display (device);
+ broadway_display = GDK_BROADWAY_DISPLAY (display);
+
+ if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
+ {
+ /* Device is a keyboard */
+ return GDK_GRAB_SUCCESS;
+ }
+ else
+ {
+ /* Device is a pointer */
+ return _gdk_broadway_server_grab_pointer (broadway_display->server,
+ GDK_WINDOW_IMPL_BROADWAY (window->impl)->id,
+ owner_events,
+ event_mask,
+ time_);
+ }
}
+#define TIME_IS_LATER(time1, time2) \
+ ( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) || \
+ (( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 )) \
+ )
+
static void
gdk_broadway_device_ungrab (GdkDevice *device,
guint32 time_)
{
+ GdkDisplay *display;
+ GdkBroadwayDisplay *broadway_display;
+ GdkDeviceGrabInfo *grab;
+ guint32 serial;
+
+ display = gdk_device_get_display (device);
+ broadway_display = GDK_BROADWAY_DISPLAY (display);
+
+ if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
+ {
+ /* Device is a keyboard */
+ }
+ else
+ {
+ /* Device is a pointer */
+ serial = _gdk_broadway_server_ungrab_pointer (broadway_display->server, time_);
+
+ if (serial != 0)
+ {
+ grab = _gdk_display_get_last_device_grab (display, device);
+ if (grab &&
+ (time_ == GDK_CURRENT_TIME ||
+ grab->time == GDK_CURRENT_TIME ||
+ !TIME_IS_LATER (grab->time, time_)))
+ grab->serial_end = serial;
+ }
+ }
}
static GdkWindow *
GdkModifierType *mask,
gboolean get_toplevel)
{
- return NULL;
+ GdkScreen *screen;
+ GdkWindow *root_window;
+ GdkWindow *window;
+
+ screen = gdk_screen_get_default ();
+ root_window = gdk_screen_get_root_window (screen);
+
+ gdk_broadway_device_query_state (device, root_window, NULL, &window, NULL, NULL, win_x, win_y, mask);
+
+ return window;
}
static void