static void
clutter_stage_win32_set_fullscreen (ClutterStageWindow *stage_window,
				    gboolean            value)
{
  ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (stage_window);
  HWND hwnd = CLUTTER_STAGE_WIN32 (stage_window)->hwnd;
  LONG old_style = GetWindowLongW (hwnd, GWL_STYLE);
  ClutterStageStateEvent event;

  if (value)
    stage_win32->state |= CLUTTER_STAGE_STATE_FULLSCREEN;
  else
    stage_win32->state &= ~CLUTTER_STAGE_STATE_FULLSCREEN;

  if (hwnd)
    {
      /* Update the window style but preserve the visibility */
      SetWindowLongW (hwnd, GWL_STYLE,
		      get_window_style (stage_win32)
		      | (old_style & WS_VISIBLE));
      /* Update the window size */
      if (value)
	{
	  get_fullscreen_rect (stage_win32);
	  SetWindowPos (hwnd, HWND_TOP,
			stage_win32->fullscreen_rect.left,
			stage_win32->fullscreen_rect.top,
			stage_win32->fullscreen_rect.right
			- stage_win32->fullscreen_rect.left,
			stage_win32->fullscreen_rect.bottom
			- stage_win32->fullscreen_rect.top,
			0);
	}
      else
	{
	  int full_width, full_height;

	  get_full_window_size (stage_win32,
				stage_win32->win_width,
				stage_win32->win_height,
				&full_width, &full_height);

	  SetWindowPos (stage_win32->hwnd, NULL,
			0, 0,
			full_width, full_height,
			SWP_NOZORDER | SWP_NOMOVE);
	}

      CLUTTER_SET_PRIVATE_FLAGS (stage_win32->wrapper,
				 CLUTTER_ACTOR_SYNC_MATRICES);
    }

  /* Report the state change */
  memset (&event, 0, sizeof (event));
  event.type = CLUTTER_STAGE_STATE;
  event.stage = CLUTTER_STAGE (stage_win32->wrapper);
  event.new_state = stage_win32->state;
  event.changed_mask = CLUTTER_STAGE_STATE_FULLSCREEN;
  clutter_event_put ((ClutterEvent *) &event);
}
static void
clutter_stage_win32_set_fullscreen (ClutterStageWindow *stage_window,
				    gboolean            value)
{
  ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (stage_window);
  HWND hwnd = CLUTTER_STAGE_WIN32 (stage_window)->hwnd;
  LONG old_style = GetWindowLongW (hwnd, GWL_STYLE);
  ClutterStageStateEvent event;

  if (hwnd)
    {
      /* Update the window style but preserve the visibility */
      SetWindowLongW (hwnd, GWL_STYLE,
		      get_requested_window_style (stage_win32, value)
		      | (old_style & WS_VISIBLE));
      /* Update the window size */
      if (value)
        {
          get_fullscreen_rect (stage_win32);
          SetWindowPos (hwnd, HWND_TOP,
                        stage_win32->fullscreen_rect.left,
                        stage_win32->fullscreen_rect.top,
                        stage_win32->fullscreen_rect.right
                        - stage_win32->fullscreen_rect.left,
                        stage_win32->fullscreen_rect.bottom
                        - stage_win32->fullscreen_rect.top,
                        0);
        }
      else
        {
          int full_width, full_height;

          get_full_window_size (stage_win32,
                                stage_win32->win_width,
                                stage_win32->win_height,
                                &full_width, &full_height);

          SetWindowPos (stage_win32->hwnd, NULL,
                        0, 0,
                        full_width, full_height,
                        SWP_NOZORDER | SWP_NOMOVE);
        }
    }

  /* Report the state change */
  if (value)
    {
      _clutter_stage_update_state (stage_win32->wrapper,
                                   0,
                                   CLUTTER_STAGE_STATE_FULLSCREEN);
    }
  else
    {
      _clutter_stage_update_state (stage_win32->wrapper,
                                   CLUTTER_STAGE_STATE_FULLSCREEN,
                                   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;
}
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);
}