예제 #1
0
gboolean
_clutter_feature_init (GError **error)
{
  ClutterMainContext *context;

  CLUTTER_NOTE (MISC, "checking features");

  if (!__features)
    {
      CLUTTER_NOTE (MISC, "allocating features data");
      __features = g_new0 (ClutterFeatures, 1);
      __features->features_set = FALSE; /* don't rely on zero-ing */
    }

  if (__features->features_set)
    return TRUE;

  context = _clutter_context_get_default ();

  /* makes sure we have a GL context; if we have, this is a no-op */
  if (!_clutter_backend_create_context (context->backend, error))
    return FALSE;

  __features->flags = (clutter_features_from_cogl (cogl_get_features ())
                    | _clutter_backend_get_features (context->backend));

  __features->features_set = TRUE;

  CLUTTER_NOTE (MISC, "features checked");

  return TRUE;
}
예제 #2
0
static gboolean
clutter_stage_win32_realize (ClutterStageWindow *stage_window)
{
  ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (stage_window);
  ClutterBackend *backend;
  ClutterBackendWin32 *backend_win32;
  CoglFramebuffer *framebuffer;
  gfloat width;
  gfloat height;
  GError *error = NULL;

  CLUTTER_NOTE (MISC, "Realizing main stage");

  backend = CLUTTER_BACKEND (stage_win32->backend);
  backend_win32 = CLUTTER_BACKEND_WIN32 (backend);

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

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

  if (stage_win32->hwnd == NULL)
    {
      ATOM window_class = clutter_stage_win32_get_window_class ();
      int win_xpos, win_ypos, win_width, win_height;

      if (window_class == 0)
        {
          g_critical ("Unable to register window class");
          goto fail;
        }

      /* If we're in fullscreen mode then use the fullscreen rect
         instead */
      if (_clutter_stage_is_fullscreen (stage_win32->wrapper))
        {
          get_fullscreen_rect (stage_win32);
          win_xpos = stage_win32->fullscreen_rect.left;
          win_ypos = stage_win32->fullscreen_rect.top;
          win_width = stage_win32->fullscreen_rect.right - win_xpos;
          win_height = stage_win32->fullscreen_rect.bottom - win_ypos;
        }
      else
        {
          win_xpos = win_ypos = CW_USEDEFAULT;

          get_full_window_size (stage_win32,
                                stage_win32->win_width,
                                stage_win32->win_height,
                                &win_width, &win_height);
        }

      if (stage_win32->wtitle == NULL)
        stage_win32->wtitle = g_utf8_to_utf16 (".", -1, NULL, NULL, NULL);

      stage_win32->hwnd = CreateWindowW ((LPWSTR) MAKEINTATOM (window_class),
					 stage_win32->wtitle,
					 get_window_style (stage_win32),
					 win_xpos,
					 win_ypos,
					 win_width,
					 win_height,
					 NULL, NULL,
					 GetModuleHandle (NULL),
					 NULL);

      if (stage_win32->hwnd == NULL)
        {
          g_critical ("Unable to create stage window");
          goto fail;
        }

      /* Store a pointer to the actor in the extra bytes of the window
         so we can quickly access it in the window procedure */
      SetWindowLongPtrW (stage_win32->hwnd, 0, (LONG_PTR) stage_win32);
    }

  cogl_win32_onscreen_set_foreign_window (stage_win32->onscreen,
                                          stage_win32->hwnd);

  cogl_onscreen_set_swap_throttled (stage_win32->onscreen,
                                    _clutter_get_sync_to_vblank ());

  framebuffer = COGL_FRAMEBUFFER (stage_win32->onscreen);
  if (!cogl_framebuffer_allocate (framebuffer, &error))
    {
      g_warning ("Failed to allocate stage: %s", error->message);
      g_error_free (error);
      cogl_object_unref (stage_win32->onscreen);
      stage_win32->onscreen = NULL;
      goto fail;
    }

  /* Create a context. This will be a no-op if we already have one */
  if (!_clutter_backend_create_context (CLUTTER_BACKEND (backend_win32),
                                        &error))
    {
      g_critical ("Unable to realize stage: %s", error->message);
      g_error_free (error);
      goto fail;
    }

  CLUTTER_NOTE (BACKEND, "Successfully realized stage");

  return TRUE;

 fail:
  return FALSE;
}
예제 #3
0
static gboolean
clutter_stage_glx_realize (ClutterStageWindow *stage_window)
{
  ClutterStageX11   *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
  ClutterStageGLX   *stage_glx = CLUTTER_STAGE_GLX (stage_window);
  ClutterBackend    *backend;
  ClutterBackendGLX *backend_glx;
  ClutterBackendX11 *backend_x11;
  GError            *error;

  CLUTTER_NOTE (ACTOR, "Realizing stage '%s' [%p]",
                G_OBJECT_TYPE_NAME (stage_window),
                stage_window);

  backend     = clutter_get_default_backend ();
  backend_glx = CLUTTER_BACKEND_GLX (backend);
  backend_x11 = CLUTTER_BACKEND_X11 (backend);

  if (stage_x11->xwin == None)
    {
      XSetWindowAttributes xattr;
      unsigned long mask;
      XVisualInfo *xvisinfo;
      gfloat width, height;

      CLUTTER_NOTE (MISC, "Creating stage X window");

      xvisinfo = clutter_backend_x11_get_visual_info (backend_x11);
      if (xvisinfo == NULL)
        {
          g_critical ("Unable to find suitable GL visual.");
          return FALSE;
        }

      /* window attributes */
      xattr.background_pixel = WhitePixel (backend_x11->xdpy,
                                           backend_x11->xscreen_num);
      xattr.border_pixel = 0;
      xattr.colormap = XCreateColormap (backend_x11->xdpy,
                                        backend_x11->xwin_root,
                                        xvisinfo->visual,
                                        AllocNone);
      mask = CWBorderPixel | CWColormap;

      /* Call get_size - this will either get the geometry size (which
       * before we create the window is set to 640x480), or if a size
       * is set, it will get that. This lets you set a size on the
       * stage before it's realized.
       */
      clutter_actor_get_size (CLUTTER_ACTOR (stage_x11->wrapper),
                              &width,
                              &height);
      stage_x11->xwin_width = (gint)width;
      stage_x11->xwin_height = (gint)height;

      stage_x11->xwin = XCreateWindow (backend_x11->xdpy,
                                       backend_x11->xwin_root,
                                       0, 0,
                                       stage_x11->xwin_width,
                                       stage_x11->xwin_height,
                                       0,
                                       xvisinfo->depth,
                                       InputOutput,
                                       xvisinfo->visual,
                                       mask, &xattr);

      CLUTTER_NOTE (BACKEND, "Stage [%p], window: 0x%x, size: %dx%d",
                    stage_window,
                    (unsigned int) stage_x11->xwin,
                    stage_x11->xwin_width,
                    stage_x11->xwin_height);

      XFree (xvisinfo);
    }

  if (stage_glx->glxwin == None)
    {
      int major;
      int minor;
      GLXFBConfig config;

      /* Try and create a GLXWindow to use with extensions dependent on
       * GLX versions >= 1.3 that don't accept regular X Windows as GLX
       * drawables. */
      if (glXQueryVersion (backend_x11->xdpy, &major, &minor) &&
          major == 1 && minor >= 3 &&
          _clutter_backend_glx_get_fbconfig (backend_glx, &config))
        {
          stage_glx->glxwin = glXCreateWindow (backend_x11->xdpy,
                                               config,
                                               stage_x11->xwin,
                                               NULL);
        }
    }

  if (clutter_x11_has_event_retrieval ())
    {
      if (clutter_x11_has_xinput ())
        {
          XSelectInput (backend_x11->xdpy, stage_x11->xwin,
                        StructureNotifyMask |
                        FocusChangeMask |
                        ExposureMask |
                        KeyPressMask | KeyReleaseMask |
                        EnterWindowMask | LeaveWindowMask |
                        PropertyChangeMask);
#ifdef HAVE_XINPUT
          _clutter_x11_select_events (stage_x11->xwin);
#endif
        }
      else
        XSelectInput (backend_x11->xdpy, stage_x11->xwin,
                      StructureNotifyMask |
                      FocusChangeMask |
                      ExposureMask |
                      PointerMotionMask |
                      KeyPressMask | KeyReleaseMask |
                      ButtonPressMask | ButtonReleaseMask |
                      EnterWindowMask | LeaveWindowMask |
                      PropertyChangeMask);

#ifdef GLX_INTEL_swap_event
      if (clutter_feature_available (CLUTTER_FEATURE_SWAP_EVENTS))
        {
          GLXDrawable drawable =
            stage_glx->glxwin ? stage_glx->glxwin : stage_x11->xwin;
          glXSelectEvent (backend_x11->xdpy,
                          drawable,
                          GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK);
        }
#endif /* GLX_INTEL_swap_event */
    }

  /* no user resize.. */
  clutter_stage_x11_fix_window_size (stage_x11,
                                     stage_x11->xwin_width,
                                     stage_x11->xwin_height);
  clutter_stage_x11_set_wm_protocols (stage_x11);

  /* ask for a context; a no-op, if a context already exists */
  error = NULL;
  _clutter_backend_create_context (backend, &error);
  if (error)
    {
      g_critical ("Unable to realize stage: %s", error->message);
      g_error_free (error);
      return FALSE;
    }

  CLUTTER_NOTE (BACKEND, "Successfully realized stage");

  /* chain up to the StageX11 implementation */
  return clutter_stage_glx_parent_iface->realize (stage_window);
}