static gulong
gdk_broadway_display_get_next_serial (GdkDisplay *display)
{
    GdkBroadwayDisplay *broadway_display;
    broadway_display = GDK_BROADWAY_DISPLAY (display);

    return _gdk_broadway_server_get_next_serial (broadway_display->server);
}
Exemple #2
0
static void
gdk_broadway_display_flush (GdkDisplay *display)
{
  GdkBroadwayDisplay *broadway_display = GDK_BROADWAY_DISPLAY (display);

  g_return_if_fail (GDK_IS_BROADWAY_DISPLAY (display));

  _gdk_broadway_server_flush (broadway_display->server);
}
static GdkGrabStatus
gdk_broadway_device_grab (GdkDevice    *device,
			  GdkWindow    *window,
			  gboolean      owner_events,
			  GdkEventMask  event_mask,
			  GdkWindow    *confine_to,
			  GdkCursor    *cursor,
			  guint32       time_)
{
  GdkDisplay *display;
  GdkBroadwayDisplay *broadway_display;
  GdkWindowImplBroadway *impl;
  guint32 serial;
  char *reply;

  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 */

      if (broadway_display->output)
	{
	  impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);

	  serial = broadway_output_grab_pointer (broadway_display->output,
						 impl->id, owner_events, time_);
	  reply = _gdk_broadway_display_block_for_input (display, 'g', serial, FALSE);
	  if (reply != NULL)
	    {
	      char *p;
	      char cmd;
	      guint32 reply_serial;
	      int res;

	      p = reply;

	      cmd = *p++;
	      reply_serial = (guint32)strtol(p, &p, 10);
	      p++; /* Skip , */

	      res = strtol(p, &p, 10);

	      return res;
	    }
	}

      return GDK_GRAB_NOT_VIEWABLE;
    }
}
Exemple #4
0
static void
broadway_focus_out (GtkIMContext *context)
{
  GtkIMContextBroadway *bw = GTK_IM_CONTEXT_BROADWAY (context);
  GdkDisplay *display;

  if (bw->client_window)
    {
      display = gdk_window_get_display (bw->client_window);
      gdk_broadway_display_hide_keyboard (GDK_BROADWAY_DISPLAY (display));
    }
}
Exemple #5
0
static void
gdk_broadway_display_init_input (GdkDisplay *display)
{
  GdkBroadwayDisplay *broadway_display;
  GdkDeviceManager *device_manager;
  GdkDevice *device;
  GList *list, *l;

  broadway_display = GDK_BROADWAY_DISPLAY (display);
  device_manager = gdk_display_get_device_manager (display);

  /* For backwards compatibility, just add
   * floating devices that are not keyboards.
   */
  list = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING);

  for (l = list; l; l = l->next)
    {
      device = l->data;

      if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
        continue;

      broadway_display->input_devices = g_list_prepend (broadway_display->input_devices,
                                                   g_object_ref (l->data));
    }

  g_list_free (list);

  /* Now set "core" pointer to the first
   * master device that is a pointer.
   */
  list = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);

  for (l = list; l; l = l->next)
    {
      device = l->data;

      if (gdk_device_get_source (device) != GDK_SOURCE_MOUSE)
        continue;

      display->core_pointer = device;
      break;
    }

  /* Add the core pointer to the devices list */
  broadway_display->input_devices = g_list_prepend (broadway_display->input_devices,
                                               g_object_ref (display->core_pointer));

  g_list_free (list);
}
Exemple #6
0
GdkDisplay *
_gdk_broadway_display_open (const gchar *display_name)
{
  GdkDisplay *display;
  GdkBroadwayDisplay *broadway_display;
  GError *error = NULL;

  display = g_object_new (GDK_TYPE_BROADWAY_DISPLAY, NULL);
  broadway_display = GDK_BROADWAY_DISPLAY (display);

  /* initialize the display's screens */
  broadway_display->screens = g_new (GdkScreen *, 1);
  broadway_display->screens[0] = _gdk_broadway_screen_new (display, 0);

  /* We need to initialize events after we have the screen
   * structures in places
   */
  _gdk_broadway_screen_events_init (broadway_display->screens[0]);

  /*set the default screen */
  broadway_display->default_screen = broadway_display->screens[0];

  display->device_manager = _gdk_broadway_device_manager_new (display);

  gdk_event_init (display);

  gdk_broadway_display_init_input (display);
  _gdk_broadway_display_init_dnd (display);

  _gdk_broadway_screen_setup (broadway_display->screens[0]);

  if (display_name == NULL)
    display_name = g_getenv ("BROADWAY_DISPLAY");

  broadway_display->server = _gdk_broadway_server_new (display_name, &error);
  if (broadway_display->server == NULL)
    {
      g_printerr ("Unable to init server: %s\n", error->message);
      g_error_free (error);
      return NULL;
    }

  g_signal_emit_by_name (display, "opened");

  return display;
}
Exemple #7
0
static void
gdk_broadway_display_dispose (GObject *object)
{
  GdkBroadwayDisplay *broadway_display = GDK_BROADWAY_DISPLAY (object);

  g_list_foreach (broadway_display->input_devices, (GFunc) g_object_run_dispose, NULL);

  _gdk_screen_close (broadway_display->screens[0]);

  if (broadway_display->event_source)
    {
      g_source_destroy (broadway_display->event_source);
      g_source_unref (broadway_display->event_source);
      broadway_display->event_source = NULL;
    }

  G_OBJECT_CLASS (gdk_broadway_display_parent_class)->dispose (object);
}
Exemple #8
0
static void
gdk_broadway_display_finalize (GObject *object)
{
  GdkBroadwayDisplay *broadway_display = GDK_BROADWAY_DISPLAY (object);

  /* Keymap */
  if (broadway_display->keymap)
    g_object_unref (broadway_display->keymap);

  _gdk_broadway_cursor_display_finalize (GDK_DISPLAY_OBJECT(broadway_display));

  /* input GdkDevice list */
  g_list_free_full (broadway_display->input_devices, g_object_unref);
  /* Free all GdkScreens */
  g_object_unref (broadway_display->screens[0]);
  g_free (broadway_display->screens);

  G_OBJECT_CLASS (gdk_broadway_display_parent_class)->finalize (object);
}
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)
{
  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;

  if (gdk_device_get_source (device) != GDK_SOURCE_MOUSE)
    return FALSE;

  display = gdk_device_get_display (device);
  broadway_display = GDK_BROADWAY_DISPLAY (display);

  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, TRUE);

      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;

  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;
  if (win_y)
    *win_y = device_root_y - window->y;
  if (child_window)
    {
      if (gdk_window_get_window_type (window) == GDK_WINDOW_ROOT)
	{
	  *child_window = broadway_display->mouse_in_toplevel;
	  if (*child_window == NULL)
	    *child_window = window;
	}
      else
	{
	  /* No native children */
	  *child_window = window;
	}
    }

  return TRUE;
}
Exemple #10
0
void
_gdk_broadway_events_got_input (BroadwayInputMsg *message)
{
  GdkDisplay *display = gdk_display_get_default ();
  GdkBroadwayDisplay *display_broadway = GDK_BROADWAY_DISPLAY (display);
  GdkBroadwayDeviceManager *device_manager;
  GdkScreen *screen;
  GdkWindow *window;
  GdkEvent *event = NULL;
  GList *node;

  device_manager = GDK_BROADWAY_DEVICE_MANAGER (gdk_display_get_device_manager (display));

  switch (message->base.type) {
  case BROADWAY_EVENT_ENTER:
    window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->pointer.event_window_id));
    if (window)
      {
	event = gdk_event_new (GDK_ENTER_NOTIFY);
	event->crossing.window = g_object_ref (window);
	event->crossing.time = message->base.time;
	event->crossing.x = message->pointer.win_x;
	event->crossing.y = message->pointer.win_y;
	event->crossing.x_root = message->pointer.root_x;
	event->crossing.y_root = message->pointer.root_y;
	event->crossing.state = message->pointer.state;
	event->crossing.mode = message->crossing.mode;
	event->crossing.detail = GDK_NOTIFY_ANCESTOR;
	gdk_event_set_device (event, display->core_pointer);

	node = _gdk_event_queue_append (display, event);
	_gdk_windowing_got_event (display, node, event, message->base.serial);
      }
    break;
  case BROADWAY_EVENT_LEAVE:
    window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->pointer.event_window_id));
    if (window)
      {
	event = gdk_event_new (GDK_LEAVE_NOTIFY);
	event->crossing.window = g_object_ref (window);
	event->crossing.time = message->base.time;
	event->crossing.x = message->pointer.win_x;
	event->crossing.y = message->pointer.win_y;
	event->crossing.x_root = message->pointer.root_x;
	event->crossing.y_root = message->pointer.root_y;
	event->crossing.state = message->pointer.state;
	event->crossing.mode = message->crossing.mode;
	event->crossing.detail = GDK_NOTIFY_ANCESTOR;
	gdk_event_set_device (event, display->core_pointer);

	node = _gdk_event_queue_append (display, event);
	_gdk_windowing_got_event (display, node, event, message->base.serial);
      }
    break;
  case BROADWAY_EVENT_POINTER_MOVE:
    if (_gdk_broadway_moveresize_handle_event (display, message))
      break;

    window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->pointer.event_window_id));
    if (window)
      {
	event = gdk_event_new (GDK_MOTION_NOTIFY);
	event->motion.window = g_object_ref (window);
	event->motion.time = message->base.time;
	event->motion.x = message->pointer.win_x;
	event->motion.y = message->pointer.win_y;
	event->motion.x_root = message->pointer.root_x;
	event->motion.y_root = message->pointer.root_y;
	event->motion.state = message->pointer.state;
	gdk_event_set_device (event, display->core_pointer);

	node = _gdk_event_queue_append (display, event);
	_gdk_windowing_got_event (display, node, event, message->base.serial);
      }

    break;
  case BROADWAY_EVENT_BUTTON_PRESS:
  case BROADWAY_EVENT_BUTTON_RELEASE:
    if (message->base.type != 'b' &&
	_gdk_broadway_moveresize_handle_event (display, message))
      break;

    window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->pointer.event_window_id));
    if (window)
      {
	event = gdk_event_new (message->base.type == 'b' ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE);
	event->button.window = g_object_ref (window);
	event->button.time = message->base.time;
	event->button.x = message->pointer.win_x;
	event->button.y = message->pointer.win_y;
	event->button.x_root = message->pointer.root_x;
	event->button.y_root = message->pointer.root_y;
	event->button.button = message->button.button;
	event->button.state = message->pointer.state;
	gdk_event_set_device (event, display->core_pointer);

	node = _gdk_event_queue_append (display, event);
	_gdk_windowing_got_event (display, node, event, message->base.serial);
      }

    break;
  case BROADWAY_EVENT_SCROLL:
    window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->pointer.event_window_id));
    if (window)
      {
	event = gdk_event_new (GDK_SCROLL);
	event->scroll.window = g_object_ref (window);
	event->scroll.time = message->base.time;
	event->scroll.x = message->pointer.win_x;
	event->scroll.y = message->pointer.win_y;
	event->scroll.x_root = message->pointer.root_x;
	event->scroll.y_root = message->pointer.root_y;
	event->scroll.direction = message->scroll.dir == 0 ? GDK_SCROLL_UP : GDK_SCROLL_DOWN;
	gdk_event_set_device (event, display->core_pointer);

	node = _gdk_event_queue_append (display, event);
	_gdk_windowing_got_event (display, node, event, message->base.serial);
      }

    break;
  case BROADWAY_EVENT_TOUCH:
    window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->touch.event_window_id));
    if (window)
      {
        GdkEventType event_type = 0;

        switch (message->touch.touch_type) {
        case 0:
          event_type = GDK_TOUCH_BEGIN;
          break;
        case 1:
          event_type = GDK_TOUCH_UPDATE;
          break;
        case 2:
          event_type = GDK_TOUCH_END;
          break;
        default:
          g_printerr ("_gdk_broadway_events_got_input - Unknown touch type %d\n", message->touch.touch_type);
        }

        if (event_type != GDK_TOUCH_BEGIN &&
            message->touch.is_emulated && _gdk_broadway_moveresize_handle_event (display, message))
          break;

	event = gdk_event_new (event_type);
	event->touch.window = g_object_ref (window);
	event->touch.sequence = GUINT_TO_POINTER(message->touch.sequence_id);
	event->touch.emulating_pointer = message->touch.is_emulated;
	event->touch.time = message->base.time;
	event->touch.x = message->touch.win_x;
	event->touch.y = message->touch.win_y;
	event->touch.x_root = message->touch.root_x;
	event->touch.y_root = message->touch.root_y;
	event->touch.state = message->touch.state;

	gdk_event_set_device (event, device_manager->core_pointer);
	gdk_event_set_source_device (event, device_manager->touchscreen);

        if (message->touch.is_emulated)
          _gdk_event_set_pointer_emulated (event, TRUE);

        if (event_type == GDK_TOUCH_BEGIN || event_type == GDK_TOUCH_UPDATE)
          event->touch.state |= GDK_BUTTON1_MASK;

	node = _gdk_event_queue_append (display, event);
	_gdk_windowing_got_event (display, node, event, message->base.serial);
      }

    break;
  case BROADWAY_EVENT_KEY_PRESS:
  case BROADWAY_EVENT_KEY_RELEASE:
    window = g_hash_table_lookup (display_broadway->id_ht,
				  GINT_TO_POINTER (message->key.window_id));
    if (window)
      {
	event = gdk_event_new (message->base.type == 'k' ? GDK_KEY_PRESS : GDK_KEY_RELEASE);
	event->key.window = g_object_ref (window);
	event->key.time = message->base.time;
	event->key.keyval = message->key.key;
	event->key.state = message->key.state;
	event->key.hardware_keycode = message->key.key;
	event->key.length = 0;
	gdk_event_set_device (event, device_manager->core_keyboard);

	node = _gdk_event_queue_append (display, event);
	_gdk_windowing_got_event (display, node, event, message->base.serial);
      }

    break;
  case BROADWAY_EVENT_GRAB_NOTIFY:
  case BROADWAY_EVENT_UNGRAB_NOTIFY:
    _gdk_display_device_grab_update (display, display->core_pointer, display->core_pointer, message->base.serial);
    break;

  case BROADWAY_EVENT_CONFIGURE_NOTIFY:
    window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->configure_notify.id));
    if (window)
      {
	window->x = message->configure_notify.x;
	window->y = message->configure_notify.y;

	event = gdk_event_new (GDK_CONFIGURE);
	event->configure.window = g_object_ref (window);
	event->configure.x = message->configure_notify.x;
	event->configure.y = message->configure_notify.y;
	event->configure.width = message->configure_notify.width;
	event->configure.height = message->configure_notify.height;

	node = _gdk_event_queue_append (display, event);
	_gdk_windowing_got_event (display, node, event, message->base.serial);

	if (window->resize_count >= 1)
	  {
	    window->resize_count -= 1;

	    if (window->resize_count == 0)
	      _gdk_broadway_moveresize_configure_done (display, window);
	  }
      }
    break;

  case BROADWAY_EVENT_DELETE_NOTIFY:
    window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->delete_notify.id));
    if (window)
      {
	event = gdk_event_new (GDK_DELETE);
	event->any.window = g_object_ref (window);

	node = _gdk_event_queue_append (display, event);
	_gdk_windowing_got_event (display, node, event, message->base.serial);
      }
    break;

  case BROADWAY_EVENT_SCREEN_SIZE_CHANGED:
    screen = gdk_display_get_default_screen (display);
    window = gdk_screen_get_root_window (screen);
    window->width = message->screen_resize_notify.width;
    window->height = message->screen_resize_notify.height;

    _gdk_window_update_size (window);
    _gdk_broadway_screen_size_changed (screen, &message->screen_resize_notify);
    break;

  case BROADWAY_EVENT_FOCUS:
    window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->focus.old_id));
    if (window)
      {
	event = gdk_event_new (GDK_FOCUS_CHANGE);
	event->focus_change.window = g_object_ref (window);
	event->focus_change.in = FALSE;
	gdk_event_set_device (event, display->core_pointer);
	node = _gdk_event_queue_append (display, event);
	_gdk_windowing_got_event (display, node, event, message->base.serial);
      }
    window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->focus.new_id));
    if (window)
      {
	event = gdk_event_new (GDK_FOCUS_CHANGE);
	event->focus_change.window = g_object_ref (window);
	event->focus_change.in = TRUE;
	gdk_event_set_device (event, display->core_pointer);
	node = _gdk_event_queue_append (display, event);
	_gdk_windowing_got_event (display, node, event, message->base.serial);
      }
    break;

  default:
    g_printerr ("_gdk_broadway_events_got_input - Unknown input command %c\n", message->base.type);
    break;
  }
}
Exemple #11
0
void
_gdk_broadway_events_got_input (GdkDisplay *display,
				BroadwayInputMsg *message)
{
  GdkBroadwayDisplay *display_broadway = GDK_BROADWAY_DISPLAY (display);
  GdkScreen *screen;
  GdkWindow *window;
  GdkEvent *event = NULL;
  GList *node;

  switch (message->base.type) {
  case 'e': /* Enter */
    display_broadway->last_x = message->pointer.root_x;
    display_broadway->last_y = message->pointer.root_y;
    display_broadway->last_state = message->pointer.state;
    display_broadway->real_mouse_in_toplevel =
      g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->pointer.mouse_window_id));

    window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->pointer.event_window_id));

    /* TODO: Unset when it dies */
    display_broadway->mouse_in_toplevel = window;
    if (window)
      {
	event = gdk_event_new (GDK_ENTER_NOTIFY);
	event->crossing.window = g_object_ref (window);
	event->crossing.time = message->base.time;
	event->crossing.x = message->pointer.win_x;
	event->crossing.y = message->pointer.win_y;
	event->crossing.x_root = message->pointer.root_x;
	event->crossing.y_root = message->pointer.root_y;
	event->crossing.state = message->pointer.state;
	event->crossing.mode = message->crossing.mode;
	event->crossing.detail = GDK_NOTIFY_ANCESTOR;
	gdk_event_set_device (event, display->core_pointer);

	node = _gdk_event_queue_append (display, event);
	_gdk_windowing_got_event (display, node, event, message->base.serial);

	event = gdk_event_new (GDK_FOCUS_CHANGE);
	event->focus_change.window = g_object_ref (window);
	event->focus_change.in = TRUE;
	gdk_event_set_device (event, display->core_pointer);

	node = _gdk_event_queue_append (display, event);
	_gdk_windowing_got_event (display, node, event, message->base.serial);
      }
    break;
  case 'l': /* Leave */
    display_broadway->last_x = message->pointer.root_x;
    display_broadway->last_y = message->pointer.root_y;
    display_broadway->last_state = message->pointer.state;
    display_broadway->real_mouse_in_toplevel =
      g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->pointer.mouse_window_id));

    window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->pointer.event_window_id));

    display_broadway->mouse_in_toplevel = NULL;
    if (window)
      {
	event = gdk_event_new (GDK_LEAVE_NOTIFY);
	event->crossing.window = g_object_ref (window);
	event->crossing.time = message->base.time;
	event->crossing.x = message->pointer.win_x;
	event->crossing.y = message->pointer.win_y;
	event->crossing.x_root = message->pointer.root_x;
	event->crossing.y_root = message->pointer.root_y;
	event->crossing.state = message->pointer.state;
	event->crossing.mode = message->crossing.mode;
	event->crossing.detail = GDK_NOTIFY_ANCESTOR;
	gdk_event_set_device (event, display->core_pointer);

	node = _gdk_event_queue_append (display, event);
	_gdk_windowing_got_event (display, node, event, message->base.serial);

	event = gdk_event_new (GDK_FOCUS_CHANGE);
	event->focus_change.window = g_object_ref (window);
	event->focus_change.in = FALSE;
	gdk_event_set_device (event, display->core_pointer);

	node = _gdk_event_queue_append (display, event);
	_gdk_windowing_got_event (display, node, event, message->base.serial);
      }
    break;
  case 'm': /* Mouse move */
    display_broadway->last_x = message->pointer.root_x;
    display_broadway->last_y = message->pointer.root_y;
    display_broadway->last_state = message->pointer.state;
    display_broadway->real_mouse_in_toplevel =
      g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->pointer.mouse_window_id));

    if (_gdk_broadway_moveresize_handle_event (display, message))
      break;

    window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->pointer.event_window_id));
    if (window)
      {
	event = gdk_event_new (GDK_MOTION_NOTIFY);
	event->motion.window = g_object_ref (window);
	event->motion.time = message->base.time;
	event->motion.x = message->pointer.win_x;
	event->motion.y = message->pointer.win_y;
	event->motion.x_root = message->pointer.root_x;
	event->motion.y_root = message->pointer.root_y;
	event->motion.state = message->pointer.state;
	gdk_event_set_device (event, display->core_pointer);

	node = _gdk_event_queue_append (display, event);
	_gdk_windowing_got_event (display, node, event, message->base.serial);
      }

    break;
  case 'b':
  case 'B':
    display_broadway->last_x = message->pointer.root_x;
    display_broadway->last_y = message->pointer.root_y;
    display_broadway->last_state = message->pointer.state;
    display_broadway->real_mouse_in_toplevel =
      g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->pointer.mouse_window_id));

    if (message->base.type != 'b' &&
	_gdk_broadway_moveresize_handle_event (display, message))
      break;

    window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->pointer.event_window_id));
    if (window)
      {
	event = gdk_event_new (message->base.type == 'b' ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE);
	event->button.window = g_object_ref (window);
	event->button.time = message->base.time;
	event->button.x = message->pointer.win_x;
	event->button.y = message->pointer.win_y;
	event->button.x_root = message->pointer.root_x;
	event->button.y_root = message->pointer.root_y;
	event->button.button = message->button.button;
	event->button.state = message->pointer.state;
	gdk_event_set_device (event, display->core_pointer);

	node = _gdk_event_queue_append (display, event);
	_gdk_windowing_got_event (display, node, event, message->base.serial);
      }

    break;
  case 's':
    display_broadway->last_x = message->pointer.root_x;
    display_broadway->last_y = message->pointer.root_y;
    display_broadway->last_state = message->pointer.state;
    display_broadway->real_mouse_in_toplevel =
      g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->pointer.mouse_window_id));

    window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->pointer.event_window_id));
    if (window)
      {
	event = gdk_event_new (GDK_SCROLL);
	event->scroll.window = g_object_ref (window);
	event->scroll.time = message->base.time;
	event->scroll.x = message->pointer.win_x;
	event->scroll.y = message->pointer.win_y;
	event->scroll.x_root = message->pointer.root_x;
	event->scroll.y_root = message->pointer.root_y;
	event->scroll.direction = message->scroll.dir == 0 ? GDK_SCROLL_UP : GDK_SCROLL_DOWN;
	gdk_event_set_device (event, display->core_pointer);

	node = _gdk_event_queue_append (display, event);
	_gdk_windowing_got_event (display, node, event, message->base.serial);
      }

    break;
  case 'k':
  case 'K':
    window = display_broadway->mouse_in_toplevel;

    if (window)
      {
	event = gdk_event_new (message->base.type == 'k' ? GDK_KEY_PRESS : GDK_KEY_RELEASE);
	event->key.window = g_object_ref (window);
	event->key.time = message->base.time;
	event->key.keyval = message->key.key;
	event->key.state = message->key.state;
	event->key.hardware_keycode = message->key.key;
	event->key.length = 0;
	gdk_event_set_device (event, display->core_pointer);

	display_broadway->last_state = message->key.state;

	node = _gdk_event_queue_append (display, event);
	_gdk_windowing_got_event (display, node, event, message->base.serial);
      }

    break;
  case 'g':
  case 'u':
    _gdk_display_device_grab_update (display, display->core_pointer, NULL, message->base.serial);
    break;

  case 'w':
    window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->configure_notify.id));
    if (window)
      {
	window->x = message->configure_notify.x;
	window->y = message->configure_notify.y;
	window->width = message->configure_notify.width;
	window->height = message->configure_notify.height;
	_gdk_window_update_size (window);
	_gdk_broadway_window_resize_surface (window);

	event = gdk_event_new (GDK_CONFIGURE);
	event->configure.window = g_object_ref (window);
	event->configure.x = message->configure_notify.x;
	event->configure.y = message->configure_notify.y;
	event->configure.width = message->configure_notify.width;
	event->configure.height = message->configure_notify.height;

	node = _gdk_event_queue_append (display, event);
	_gdk_windowing_got_event (display, node, event, message->base.serial);

	if (window->resize_count >= 1)
	  {
	    window->resize_count -= 1;

	    if (window->resize_count == 0)
	      _gdk_broadway_moveresize_configure_done (display, window);
	  }
      }
    break;

  case 'W':
    window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->delete_notify.id));
    if (window)
      {
	event = gdk_event_new (GDK_DELETE);
	event->any.window = g_object_ref (window);

	node = _gdk_event_queue_append (display, event);
	_gdk_windowing_got_event (display, node, event, message->base.serial);
      }
    break;

  case 'd':
    screen = gdk_display_get_default_screen (display);
    window = gdk_screen_get_root_window (screen);
    window->width = message->screen_resize_notify.width;
    window->height = message->screen_resize_notify.height;

    _gdk_window_update_size (window);
    _gdk_broadway_screen_size_changed (screen, &message->screen_resize_notify);
    break;

  default:
    g_printerr ("Unknown input command %c\n", message->base.type);
    break;
  }
}
static void
gdk_broadway_device_query_state (GdkDevice        *device,
                                 GdkWindow        *window,
                                 GdkWindow       **root_window,
                                 GdkWindow       **child_window,
                                 gdouble          *root_x,
                                 gdouble          *root_y,
                                 gdouble          *win_x,
                                 gdouble          *win_y,
                                 GdkModifierType  *mask)
{
    GdkWindow *toplevel;
    GdkWindowImplBroadway *impl;
    GdkDisplay *display;
    GdkBroadwayDisplay *broadway_display;
    GdkScreen *screen;
    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;

    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);
    }

    _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_x - toplevel->x;
    if (win_y)
        *win_y = device_root_y - toplevel->y;
    if (mask)
        *mask = mask32;
    if (child_window)
    {
        if (gdk_window_get_window_type (toplevel) == GDK_WINDOW_ROOT)
        {
            *child_window = mouse_toplevel;
            if (*child_window == NULL)
                *child_window = toplevel;
        }
        else
        {
            /* No native children */
            *child_window = toplevel;
        }
    }

    return;
}