/** * clutter_win32_get_stage_from_window: * @hwnd: a window handle * * Gets the stage for a particular window. * * Return value: The stage or NULL if a stage does not exist for the * window. * * Since: 0.8 */ ClutterStage * clutter_win32_get_stage_from_window (HWND hwnd) { /* Check whether the window handle is an instance of the stage window class */ if ((ATOM) GetClassLongPtrW (hwnd, GCW_ATOM) == clutter_stage_win32_get_window_class ()) /* If it is there should be a pointer to the stage in the window extra data */ return CLUTTER_STAGE_WIN32 (GetWindowLongPtrW (hwnd, 0))->wrapper; else { /* Otherwise it might be a foreign window so we should check the stage list */ ClutterStageManager *stage_manager; const GSList *stages, *l; stage_manager = clutter_stage_manager_get_default (); stages = clutter_stage_manager_peek_stages (stage_manager); for (l = stages; l != NULL; l = l->next) { ClutterStage *stage = l->data; ClutterStageWindow *impl; impl = _clutter_stage_get_window (stage); g_assert (CLUTTER_IS_STAGE_WIN32 (impl)); if (CLUTTER_STAGE_WIN32 (impl)->hwnd == hwnd) return stage; } } return NULL; }
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; }
static void clutter_stage_win32_realize (ClutterActor *actor) { ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (actor); ClutterBackendWin32 *backend_win32; PIXELFORMATDESCRIPTOR pfd; int pf; CLUTTER_NOTE (MISC, "Realizing main stage"); backend_win32 = CLUTTER_BACKEND_WIN32 (clutter_get_default_backend ()); 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 ((stage_win32->state & CLUTTER_STAGE_STATE_FULLSCREEN)) { 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.left - 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); } stage_win32->hwnd = CreateWindowW ((LPWSTR) MAKEINTATOM (window_class), L".", 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); } if (stage_win32->client_dc) ReleaseDC (stage_win32->hwnd, stage_win32->client_dc); stage_win32->client_dc = GetDC (stage_win32->hwnd); pf = clutter_stage_win32_choose_pixel_format (stage_win32->client_dc, &pfd); if (pf == 0 || !SetPixelFormat (stage_win32->client_dc, pf, &pfd)) { g_critical ("Unable to find suitable GL pixel format"); goto fail; } if (backend_win32->gl_context == NULL) { backend_win32->gl_context = wglCreateContext (stage_win32->client_dc); if (backend_win32->gl_context == NULL) { g_critical ("Unable to create suitable GL context"); goto fail; } /* Make the context current so we can check the GL version */ wglMakeCurrent (stage_win32->client_dc, backend_win32->gl_context); if (!clutter_stage_win32_check_gl_version ()) { g_critical ("OpenGL version number is too low"); goto fail; } } CLUTTER_NOTE (BACKEND, "Successfully realized stage"); return; fail: CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED); }