Example #1
0
static void x11_set_window(CoglOnscreen* onscreen, GdkWindow *window)
{
    cogl_x11_onscreen_set_foreign_window_xid(onscreen,
                                             GDK_WINDOW_XID(window),
                                             x11_window_update_foreign_event_mask,
                                             window);
    gdk_window_add_filter(window, cogl_gdk_filter, onscreen);
}
Example #2
0
static gboolean
clutter_stage_gdk_realize (ClutterStageWindow *stage_window)
{
  ClutterStageGdk *stage_gdk = CLUTTER_STAGE_GDK (stage_window);
  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
  ClutterBackend *backend = CLUTTER_BACKEND (stage_cogl->backend);
  ClutterBackendGdk *backend_gdk = CLUTTER_BACKEND_GDK (backend);
  GdkWindowAttr attributes;
  gboolean cursor_visible;
  gboolean use_alpha;
  gfloat   width, height;

  if (stage_gdk->foreign_window)
    {
      width = gdk_window_get_width (stage_gdk->window);
      height = gdk_window_get_height (stage_gdk->window);
    }
  else
    {
      if (stage_gdk->window != NULL)
        {
          /* complete realizing the stage */
          cairo_rectangle_int_t geometry;

          clutter_stage_gdk_get_geometry (stage_window, &geometry);
          clutter_actor_set_size (CLUTTER_ACTOR (stage_cogl->wrapper),
                                  geometry.width,
                                  geometry.height);

          gdk_window_ensure_native (stage_gdk->window);
          gdk_window_set_events (stage_gdk->window, CLUTTER_STAGE_GDK_EVENT_MASK);

          return TRUE;
        }
      else
        {
          attributes.title = NULL;
          g_object_get (stage_cogl->wrapper,
                        "cursor-visible", &cursor_visible,
                        "title", &attributes.title,
                        "width", &width,
                        "height", &height,
                        "use-alpha", &use_alpha,
                        NULL);

          attributes.width = width;
          attributes.height = height;
          attributes.wclass = GDK_INPUT_OUTPUT;
          attributes.window_type = GDK_WINDOW_TOPLEVEL;
          attributes.event_mask = CLUTTER_STAGE_GDK_EVENT_MASK;

          attributes.cursor = NULL;
          if (!cursor_visible)
            {
              if (stage_gdk->blank_cursor == NULL)
                stage_gdk->blank_cursor = gdk_cursor_new_for_display (backend_gdk->display, GDK_BLANK_CURSOR);

              attributes.cursor = stage_gdk->blank_cursor;
            }

          attributes.visual = NULL;
          if (use_alpha)
            {
              attributes.visual = gdk_screen_get_rgba_visual (backend_gdk->screen);

              if (attributes.visual == NULL)
                clutter_stage_set_use_alpha (stage_cogl->wrapper, FALSE);
            }

          if (attributes.visual == NULL)
            {
             /* This could still be an RGBA visual, although normally it's not */
             attributes.visual = gdk_screen_get_system_visual (backend_gdk->screen);
            }

          stage_gdk->foreign_window = FALSE;
          stage_gdk->window = gdk_window_new (NULL, &attributes,
                                              GDK_WA_TITLE | GDK_WA_CURSOR | GDK_WA_VISUAL);

          g_free (attributes.title);
        }

      clutter_stage_gdk_set_gdk_geometry (stage_gdk);
    }

  gdk_window_ensure_native (stage_gdk->window);

  g_object_set_data (G_OBJECT (stage_gdk->window),
                     "clutter-stage-window", stage_gdk);

  stage_cogl->onscreen = cogl_onscreen_new (backend->cogl_context,
					    width, height);

#if defined(GDK_WINDOWING_X11) && defined(COGL_HAS_XLIB_SUPPORT)
  if (GDK_IS_X11_WINDOW (stage_gdk->window))
    {
      cogl_x11_onscreen_set_foreign_window_xid (stage_cogl->onscreen,
                                                GDK_WINDOW_XID (stage_gdk->window),
                                                clutter_stage_gdk_update_foreign_event_mask,
                                                stage_gdk);
    }
  else
#endif
#if defined(GDK_WINDOWING_WAYLAND) && defined(COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT)
  if (GDK_IS_WAYLAND_WINDOW (stage_gdk->window))
    {
      cogl_wayland_onscreen_set_foreign_surface (stage_cogl->onscreen,
                                                 gdk_wayland_window_get_wl_surface (stage_gdk->window));
    }
  else
#endif
#if defined(GDK_WINDOWING_WIN32) && defined(COGL_HAS_WIN32_SUPPORT)
  if (GDK_IS_WIN32_WINDOW (stage_gdk->window))
    {
      cogl_win32_onscreen_set_foreign_window (stage_cogl->onscreen,
					      gdk_win32_window_get_handle (stage_gdk->window));
    }
  else
#endif
    {
      g_warning ("Cannot find an appropriate CoglWinsys for a "
		 "GdkWindow of type %s", G_OBJECT_TYPE_NAME (stage_gdk->window));

      cogl_object_unref (stage_cogl->onscreen);
      stage_cogl->onscreen = NULL;

      if (!stage_gdk->foreign_window)
        gdk_window_destroy (stage_gdk->window);

      stage_gdk->window = NULL;

      return FALSE;
    }

  return clutter_stage_window_parent_iface->realize (stage_window);
}
Example #3
0
static gboolean
clutter_stage_x11_realize (ClutterStageWindow *stage_window)
{
  ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
  ClutterBackend *backend = CLUTTER_BACKEND (stage_cogl->backend);
  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
  ClutterDeviceManager *device_manager;
  int event_flags;
  gfloat width, height;

  clutter_actor_get_size (CLUTTER_ACTOR (stage_cogl->wrapper),
			  &width, &height);

  stage_cogl->onscreen = cogl_onscreen_new (backend->cogl_context,
                                            width, height);

  /* We just created a window of the size of the actor. No need to fix
     the size of the stage, just update it. */
  stage_x11->xwin_width = width;
  stage_x11->xwin_height = height;

  if (stage_x11->xwin != None)
    {
      cogl_x11_onscreen_set_foreign_window_xid (stage_cogl->onscreen,
                                                stage_x11->xwin,
                                                _clutter_stage_x11_update_foreign_event_mask,
                                                stage_x11);

    }

  /* Chain to the parent class now. ClutterStageCogl will call cogl_framebuffer_allocate,
     which will create the X Window we need */

  if (!(clutter_stage_window_parent_iface->realize (stage_window)))
    return FALSE;

  if (stage_x11->xwin == None)
    stage_x11->xwin = cogl_x11_onscreen_get_window_xid (stage_cogl->onscreen);

  if (clutter_stages_by_xid == NULL)
    clutter_stages_by_xid = g_hash_table_new (NULL, NULL);

  g_hash_table_insert (clutter_stages_by_xid,
                       GINT_TO_POINTER (stage_x11->xwin),
                       stage_x11);

  set_wm_pid (stage_x11);
  set_wm_title (stage_x11);
  set_cursor_visible (stage_x11);


  /* the masks for the events we want to select on a stage window;
   * KeyPressMask and KeyReleaseMask are necessary even with XI1
   * because key events are broken with that extension, and will
   * be fixed by XI2
   */
  event_flags = CLUTTER_STAGE_X11_EVENT_MASK;

  /* we unconditionally select input events even with event retrieval
   * disabled because we need to guarantee that the Clutter internal
   * state is maintained when calling clutter_x11_handle_event() without
   * requiring applications or embedding toolkits to select events
   * themselves. if we did that, we'd have to document the events to be
   * selected, and also update applications and embedding toolkits each
   * time we added a new mask, or a new class of events.
   *
   * see: http://bugzilla.clutter-project.org/show_bug.cgi?id=998
   * for the rationale of why we did conditional selection. it is now
   * clear that a compositor should clear out the input region, since
   * it cannot assume a perfectly clean slate coming from us.
   *
   * see: http://bugzilla.clutter-project.org/show_bug.cgi?id=2228
   * for an example of things that break if we do conditional event
   * selection.
   */
  XSelectInput (backend_x11->xdpy, stage_x11->xwin, event_flags);

  /* input events also depent on the actual device, so we need to
   * use the device manager to let every device select them, using
   * the event mask we passed to XSelectInput as the template
   */
  device_manager = clutter_device_manager_get_default ();
  if (G_UNLIKELY (device_manager != NULL))
    {
      _clutter_device_manager_select_stage_events (device_manager,
                                                   stage_cogl->wrapper,
                                                   event_flags);

      g_signal_connect (device_manager, "device-added",
                        G_CALLBACK (stage_events_device_added),
                        stage_window);
    }

  clutter_stage_x11_fix_window_size (stage_x11,
                                     stage_x11->xwin_width,
                                     stage_x11->xwin_height);
  clutter_stage_x11_set_wm_protocols (stage_x11);

  if (stage_x11->fullscreen_on_realize)
    {
      stage_x11->fullscreen_on_realize = FALSE;

      clutter_stage_x11_set_fullscreen (stage_window, TRUE);
    }

  CLUTTER_NOTE (BACKEND, "Successfully realized stage");

  return TRUE;
}