Exemple #1
0
void
_gdk_gl_pixmap_destroy (GdkGLPixmap *glpixmap)
{
  GdkGLPixmapImplX11 *impl = GDK_GL_PIXMAP_IMPL_X11 (glpixmap);
  Display *xdisplay;

  GDK_GL_NOTE_FUNC_PRIVATE ();

  if (impl->is_destroyed)
    return;

  xdisplay = GDK_GL_CONFIG_XDISPLAY (impl->glconfig);

  if (impl->glxpixmap == glXGetCurrentDrawable ())
    {
      glXWaitGL ();

      GDK_GL_NOTE_FUNC_IMPL ("glXMakeCurrent");
      glXMakeCurrent (xdisplay, None, NULL);
    }

  GDK_GL_NOTE_FUNC_IMPL ("glXDestroyGLXPixmap");
  glXDestroyGLXPixmap (xdisplay, impl->glxpixmap);

  impl->glxpixmap = None;

  impl->is_destroyed = TRUE;
}
Exemple #2
0
void
_gdk_gl_window_destroy (GdkGLWindow *glwindow)
{
  GdkGLWindowImplX11 *impl = GDK_GL_WINDOW_IMPL_X11 (glwindow);
  Display *xdisplay;
  GdkGL_GLX_MESA_release_buffers *mesa_ext;

  GDK_GL_NOTE_FUNC_PRIVATE ();

  if (impl->is_destroyed)
    return;

  xdisplay = GDK_GL_CONFIG_XDISPLAY (impl->glconfig);

  if (impl->glxwindow == glXGetCurrentDrawable ())
    {
      glXWaitGL ();

      GDK_GL_NOTE_FUNC_IMPL ("glXMakeCurrent");
      glXMakeCurrent (xdisplay, None, NULL);
    }

  /* If GLX_MESA_release_buffers is supported. */
  mesa_ext = gdk_gl_get_GLX_MESA_release_buffers (impl->glconfig);
  if (mesa_ext)
    {
      GDK_GL_NOTE_FUNC_IMPL ("glXReleaseBuffersMESA");
      mesa_ext->glXReleaseBuffersMESA (xdisplay, impl->glxwindow);
    }

  impl->glxwindow = None;

  impl->is_destroyed = TRUE;
}
/*< private >*/
GdkGLContextImpl *
_gdk_win32_gl_context_impl_new (GdkGLContext  *glcontext,
                                GdkGLDrawable *gldrawable,
                                GdkGLContext  *share_list,
                                gboolean       direct,
                                int            render_type)
{
  GdkGLConfig *glconfig;
  HDC hdc;
  HGLRC hglrc;
  GdkGLContextImplWin32 *share_impl = NULL;

  GDK_GL_NOTE_FUNC_PRIVATE ();

  /*
   * Create an OpenGL rendering context.
   */

  glconfig = gdk_gl_drawable_get_gl_config (gldrawable);

  /* Get DC. */
  hdc = gdk_win32_gl_window_get_hdc (GDK_GL_WINDOW (gldrawable));
  if (hdc == NULL)
    return NULL;

  GDK_GL_NOTE_FUNC_IMPL ("wglCreateContext");

  hglrc = wglCreateContext (hdc);

  /* Release DC. */
  gdk_win32_gl_window_release_hdc (GDK_GL_WINDOW (gldrawable));

  if (hglrc == NULL)
    return NULL;

  if (share_list != NULL && GDK_IS_GL_CONTEXT (share_list))
    {
      GDK_GL_NOTE_FUNC_IMPL ("wglShareLists");

      share_impl = GDK_GL_CONTEXT_IMPL_WIN32 (share_list);
      if (!wglShareLists (share_impl->hglrc, hglrc))
        {
          wglDeleteContext (hglrc);
          return NULL;
        }
    }

  /*
   * Instantiate the GdkGLContextImplWin32 object.
   */

  return gdk_win32_gl_context_impl_new_common (glcontext,
                                               glconfig,
                                               share_list,
                                               render_type,
                                               hglrc,
                                               FALSE);
}
void
_gdk_gl_pixmap_destroy (GdkGLPixmap *glpixmap)
{
  GdkGLPixmapImplWin32 *impl = GDK_GL_PIXMAP_IMPL_WIN32 (glpixmap);

  GDK_GL_NOTE_FUNC_PRIVATE ();

  if (impl->is_destroyed)
    return;

  if (impl->hdc_gl == wglGetCurrentDC ())
    {
      glFinish ();

      GDK_GL_NOTE_FUNC_IMPL ("wglMakeCurrent");
      wglMakeCurrent (NULL, NULL);
    }

  DeleteDC (impl->hdc_gl);
  impl->hdc_gl = NULL;

  DeleteDC (impl->hdc_gdk);
  impl->hdc_gdk = NULL;

  g_object_unref (G_OBJECT (impl->pixmap_gl));
  impl->pixmap_gl = NULL;

  impl->is_destroyed = TRUE;
}
static void
_gdk_win32_gl_window_impl_destroy (GdkGLWindow *glwindow)
{
  GdkGLWindowImplWin32 *impl = GDK_GL_WINDOW_IMPL_WIN32 (glwindow->impl);

  GDK_GL_NOTE_FUNC_PRIVATE ();

  if (impl->is_destroyed)
    return;

  /* Get DC. */
  if (impl->hdc == NULL)
    {
      impl->hdc = GetDC (impl->hwnd);
      if (impl->hdc == NULL)
        return;
    }

  if (impl->hdc == wglGetCurrentDC ())
    {
      glFinish ();

      GDK_GL_NOTE_FUNC_IMPL ("wglMakeCurrent");
      wglMakeCurrent (NULL, NULL);
    }

  /* Release DC. */
  if (impl->need_release_dc)
    ReleaseDC (impl->hwnd, impl->hdc);
  impl->hdc = NULL;

  impl->hwnd = NULL;

  impl->is_destroyed = TRUE;
}
static gboolean
_gdk_win32_gl_context_impl_make_current (GdkGLContext *glcontext,
                                         GdkGLDrawable *draw,
                                         GdkGLDrawable *read)
{
  GdkGLWindowImplWin32 *impl;
  HDC hdc;
  HGLRC hglrc;

  g_return_val_if_fail (GDK_IS_WIN32_GL_CONTEXT (glcontext), FALSE);
  g_return_val_if_fail (GDK_IS_WIN32_GL_WINDOW (draw), FALSE);

  if (GDK_GL_WINDOW_IS_DESTROYED (GDK_GL_WINDOW (draw)) ||
      GDK_GL_CONTEXT_IS_DESTROYED (glcontext))
    return FALSE;

  impl = GDK_GL_WINDOW_IMPL_WIN32 (GDK_GL_WINDOW (draw)->impl);

  /* Get DC. */
  hdc = GDK_GL_WINDOW_IMPL_WIN32_HDC_GET (impl);

  /* Get GLRC. */
  hglrc = GDK_GL_CONTEXT_HGLRC (glcontext);

  GDK_GL_NOTE_FUNC_IMPL ("wglMakeCurrent");

  if (!wglMakeCurrent (hdc, hglrc))
    {
      g_warning ("wglMakeCurrent() failed");
      _gdk_gl_context_set_gl_drawable (glcontext, NULL);
      /* currently unused. */
      /* _gdk_gl_context_set_gl_drawable_read (glcontext, NULL); */
      return FALSE;
    }

  _gdk_gl_context_set_gl_drawable (glcontext, draw);
  /* currently unused. */
  /* _gdk_gl_context_set_gl_drawable_read (glcontext, read); */

  if (_GDK_GL_CONFIG_AS_SINGLE_MODE (impl->glconfig))
    {
      /* We do this because we are treating a double-buffered frame
         buffer as a single-buffered frame buffer because the system
         does not appear to export any suitable single-buffered
         visuals (in which the following are necessary). */
      glDrawBuffer (GL_FRONT);
      glReadBuffer (GL_FRONT);
    }

  GDK_GL_NOTE (MISC, _gdk_gl_print_gl_info ());

  /*
   * Do *NOT* release DC.
   *
   * With some graphics card, DC owned by rendering thread will be needed.
   */

  return TRUE;
}
static void
_gdk_win32_gl_context_impl_destroy (GdkGLContext *glcontext)
{
  GdkGLContextImplWin32 *impl = GDK_GL_CONTEXT_IMPL_WIN32 (glcontext->impl);

  GDK_GL_NOTE_FUNC_PRIVATE ();

  if (impl->is_destroyed)
    return;

  gdk_gl_context_remove (glcontext);

  if (impl->hglrc == wglGetCurrentContext ())
    {
      glFinish ();

      GDK_GL_NOTE_FUNC_IMPL ("wglMakeCurrent");
      wglMakeCurrent (NULL, NULL);
    }

  if (!impl->is_foreign)
    {
      GDK_GL_NOTE_FUNC_IMPL ("wglDeleteContext");
      wglDeleteContext (impl->hglrc);
      impl->hglrc = NULL;
    }

  if (impl->gldrawable != NULL)
    {
      g_object_remove_weak_pointer (G_OBJECT (impl->gldrawable),
                                    (gpointer *) &(impl->gldrawable));
      impl->gldrawable = NULL;
    }

  /* currently unused. */
  /*
  if (impl->gldrawable_read != NULL)
    {
      g_object_remove_weak_pointer (G_OBJECT (impl->gldrawable_read),
                                    (gpointer *) &(impl->gldrawable_read));
      impl->gldrawable_read = NULL;
    }
  */

  impl->is_destroyed = TRUE;
}
Exemple #8
0
static gboolean
gdk_gl_pixmap_impl_x11_make_context_current (GdkGLDrawable *draw,
                                             GdkGLDrawable *read,
                                             GdkGLContext  *glcontext)
{
  GdkGLConfig *glconfig;
  GLXPixmap glxpixmap;
  GLXContext glxcontext;

  g_return_val_if_fail (GDK_IS_GL_PIXMAP_IMPL_X11 (draw), FALSE);
  g_return_val_if_fail (GDK_IS_GL_CONTEXT_IMPL_X11 (glcontext), FALSE);

  glconfig = GDK_GL_PIXMAP_IMPL_X11 (draw)->glconfig;
  glxpixmap = GDK_GL_PIXMAP_IMPL_X11 (draw)->glxpixmap;
  glxcontext = GDK_GL_CONTEXT_GLXCONTEXT (glcontext);

  if (glxpixmap == None || glxcontext == NULL)
    return FALSE;

#ifdef GDKGLEXT_MULTIHEAD_SUPPORT
  GDK_GL_NOTE (MISC,
    g_message (" -- Pixmap: screen number = %d",
      GDK_SCREEN_XNUMBER (gdk_drawable_get_screen (GDK_DRAWABLE (draw)))));
#endif /* GDKGLEXT_MULTIHEAD_SUPPORT */
  GDK_GL_NOTE (MISC,
    g_message (" -- Pixmap: visual id = 0x%lx",
      GDK_VISUAL_XVISUAL (gdk_drawable_get_visual (GDK_DRAWABLE (draw)))->visualid));

  GDK_GL_NOTE_FUNC_IMPL ("glXMakeCurrent");

  if (!glXMakeCurrent (GDK_GL_CONFIG_XDISPLAY (glconfig), glxpixmap, glxcontext))
    {
      g_warning ("glXMakeCurrent() failed");
      _gdk_gl_context_set_gl_drawable (glcontext, NULL);
      /* currently unused. */
      /* _gdk_gl_context_set_gl_drawable_read (glcontext, NULL); */
      return FALSE;
    }

  _gdk_gl_context_set_gl_drawable (glcontext, draw);
  /* currently unused. */
  /* _gdk_gl_context_set_gl_drawable_read (glcontext, read); */

  if (_GDK_GL_CONFIG_AS_SINGLE_MODE (glconfig))
    {
      /* We do this because we are treating a double-buffered frame
         buffer as a single-buffered frame buffer because the system
         does not appear to export any suitable single-buffered
         visuals (in which the following are necessary). */
      glDrawBuffer (GL_FRONT);
      glReadBuffer (GL_FRONT);
    }

  GDK_GL_NOTE (MISC, _gdk_gl_print_gl_info ());

  return TRUE;
}
static gboolean
gdk_gl_pixmap_impl_win32_make_context_current (GdkGLDrawable *draw,
                                               GdkGLDrawable *read,
                                               GdkGLContext  *glcontext)
{
  GdkGLPixmapImplWin32 *impl;
  HDC hdc;
  HGLRC hglrc;

  g_return_val_if_fail (GDK_IS_GL_PIXMAP_IMPL_WIN32 (draw), FALSE);
  g_return_val_if_fail (GDK_IS_GL_CONTEXT_IMPL_WIN32 (glcontext), FALSE);

  if (GDK_GL_PIXMAP_IS_DESTROYED (draw) ||
      GDK_GL_CONTEXT_IS_DESTROYED (glcontext))
    return FALSE;

  impl = GDK_GL_PIXMAP_IMPL_WIN32 (draw);

  /* Get DC. */
  hdc = GDK_GL_PIXMAP_IMPL_WIN32_HDC_GET (impl);

  /* Get GLRC. */
  hglrc = GDK_GL_CONTEXT_HGLRC (glcontext);

  GDK_GL_NOTE_FUNC_IMPL ("wglMakeCurrent");

  if (!wglMakeCurrent (hdc, hglrc))
    {
      _gdk_gl_context_set_gl_drawable (glcontext, NULL);
      /* currently unused. */
      /* _gdk_gl_context_set_gl_drawable_read (glcontext, NULL); */
      return FALSE;
    }

  _gdk_gl_context_set_gl_drawable (glcontext, draw);
  /* currently unused. */
  /* _gdk_gl_context_set_gl_drawable_read (glcontext, read); */

  if (_GDK_GL_CONFIG_AS_SINGLE_MODE (impl->glconfig))
    {
      /* We do this because we are treating a double-buffered frame
         buffer as a single-buffered frame buffer because the system
         does not appear to export any suitable single-buffered
         visuals (in which the following are necessary). */
      glDrawBuffer (GL_FRONT);
      glReadBuffer (GL_FRONT);
    }

  GDK_GL_NOTE (MISC, _gdk_gl_print_gl_info ());

  /* Do *NOT* release DC. */

  return TRUE;
}
Exemple #10
0
void
gdk_gl_window_swap_buffers (GdkGLDrawable *gldrawable)
{
  g_return_if_fail (GDK_IS_GL_WINDOW(gldrawable));

  Display *xdisplay = GDK_GL_CONFIG_XDISPLAY (GDK_GL_WINDOW (gldrawable)->glconfig);
  Window glxwindow = GDK_GL_WINDOW (gldrawable)->glxwindow;

  if (glxwindow == None)
    return;

  GDK_GL_NOTE_FUNC_IMPL ("glXSwapBuffers");

  glXSwapBuffers (xdisplay, glxwindow);
}
Exemple #11
0
gboolean
gdk_gl_window_make_context_current (GdkGLDrawable *draw, GdkGLContext *glcontext)
{
  GdkGLDrawable *read = draw;
  GdkGLConfig *glconfig;
  Window glxwindow;
  GLXContext glxcontext;

  g_return_val_if_fail (GDK_IS_GL_WINDOW (draw), FALSE);
  g_return_val_if_fail (GDK_IS_GL_CONTEXT_IMPL_X11 (glcontext), FALSE);

  glconfig = GDK_GL_WINDOW (draw)->glconfig;
  glxwindow = GDK_GL_WINDOW (draw)->glxwindow;
  glxcontext = GDK_GL_CONTEXT_GLXCONTEXT (glcontext);

  if (glxwindow == None || glxcontext == NULL)
    return FALSE;

  GDK_GL_NOTE (MISC, g_message (" -- Window: screen number = %d", GDK_SCREEN_XNUMBER (gdk_drawable_get_screen (GDK_DRAWABLE (draw)))));
  GDK_GL_NOTE (MISC, g_message (" -- Window: visual id = 0x%lx", GDK_VISUAL_XVISUAL (gdk_drawable_get_visual (GDK_DRAWABLE (draw)))->visualid));

  GDK_GL_NOTE_FUNC_IMPL ("glXMakeCurrent");

  if (!glXMakeCurrent (GDK_GL_CONFIG_XDISPLAY (glconfig), glxwindow, glxcontext))
    {
      g_warning ("glXMakeCurrent() failed");
      _gdk_gl_context_set_gl_drawable (glcontext, NULL);
      return FALSE;
    }

  _gdk_gl_context_set_gl_drawable (glcontext, draw);

  if (_GDK_GL_CONFIG_AS_SINGLE_MODE (glconfig))
    {
      /* We do this because we are treating a double-buffered frame
         buffer as a single-buffered frame buffer because the system
         does not appear to export any suitable single-buffered
         visuals (in which the following are necessary). */
      glDrawBuffer (GL_FRONT);
      glReadBuffer (GL_FRONT);
    }

  GDK_GL_NOTE (MISC, _gdk_gl_print_gl_info ());

  return TRUE;
}
Exemple #12
0
static void
gdk_gl_pixmap_impl_x11_swap_buffers (GdkGLDrawable *gldrawable)
{
  Display *xdisplay;
  GLXPixmap glxpixmap;

  g_return_if_fail (GDK_IS_GL_PIXMAP_IMPL_X11 (gldrawable));

  xdisplay = GDK_GL_CONFIG_XDISPLAY (GDK_GL_PIXMAP_IMPL_X11 (gldrawable)->glconfig);
  glxpixmap = GDK_GL_PIXMAP_IMPL_X11 (gldrawable)->glxpixmap;

  if (glxpixmap == None)
    return;

  GDK_GL_NOTE_FUNC_IMPL ("glXSwapBuffers");

  glXSwapBuffers (xdisplay, glxpixmap);
}
static gboolean
_gdk_win32_gl_context_impl_copy (GdkGLContext  *glcontext,
                                 GdkGLContext  *src,
                                 unsigned long  mask)
{
  HGLRC dst_hglrc, src_hglrc;

  g_return_val_if_fail (GDK_IS_WIN32_GL_CONTEXT (glcontext->impl), FALSE);
  g_return_val_if_fail (GDK_IS_WIN32_GL_CONTEXT (src), FALSE);

  dst_hglrc = GDK_GL_CONTEXT_HGLRC (glcontext);
  if (dst_hglrc == NULL)
    return FALSE;

  src_hglrc = GDK_GL_CONTEXT_HGLRC (src);
  if (src_hglrc == NULL)
    return FALSE;

  GDK_GL_NOTE_FUNC_IMPL ("wglCopyContext");

  return wglCopyContext (src_hglrc, dst_hglrc, mask);
}
static void
gdk_gl_pixmap_impl_win32_swap_buffers (GdkGLDrawable *gldrawable)
{
  GdkGLPixmapImplWin32 *impl;
  HDC hdc;

  g_return_if_fail (GDK_IS_GL_PIXMAP_IMPL_WIN32 (gldrawable));

  if (GDK_GL_PIXMAP_IS_DESTROYED (gldrawable))
    return;

  impl = GDK_GL_PIXMAP_IMPL_WIN32 (gldrawable);

  /* Get DC. */
  hdc = GDK_GL_PIXMAP_IMPL_WIN32_HDC_GET (impl);

  GDK_GL_NOTE_FUNC_IMPL ("SwapBuffers");

  SwapBuffers (hdc);

  /* Release DC. */
  /* GDK_GL_PIXMAP_IMPL_WIN32_HDC_RELEASE (impl); */
}
static void
_gdk_win32_gl_window_impl_swap_buffers (GdkGLWindow *glwindow)
{
  GdkGLWindowImplWin32 *win32_impl;
  HDC hdc;

  g_return_if_fail (GDK_IS_WIN32_GL_WINDOW (glwindow));

  if (GDK_GL_WINDOW_IS_DESTROYED (glwindow))
    return;

  win32_impl = GDK_GL_WINDOW_IMPL_WIN32 (glwindow->impl);

  /* Get DC. */
  hdc = GDK_GL_WINDOW_IMPL_WIN32_HDC_GET (win32_impl);

  GDK_GL_NOTE_FUNC_IMPL ("SwapBuffers");

  SwapBuffers (hdc);

  /* Release DC. */
  GDK_GL_WINDOW_IMPL_WIN32_HDC_RELEASE (win32_impl);
}
/*
 * attrib_list is currently unused. This must be set to NULL or empty
 * (first attribute of None). See GLX 1.3 spec.
 */
GdkGLWindow *
_gdk_win32_gl_window_impl_new (GdkGLWindow *glwindow,
                               GdkGLConfig *glconfig,
                               GdkWindow   *window,
                               const int   *attrib_list)
{
  GdkGLWindowImplWin32 *win32_impl;

  HWND hwnd;
  DWORD wndclass_style;
  gboolean need_release_dc;
  HDC hdc = NULL;
  PIXELFORMATDESCRIPTOR pfd;
  int pixel_format;

  GDK_GL_NOTE_FUNC ();

  g_return_val_if_fail (GDK_IS_WIN32_GL_WINDOW (glwindow), NULL);
  g_return_val_if_fail (GDK_IS_WIN32_GL_CONFIG (glconfig), NULL);
  g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);

  hwnd = (HWND) gdk_win32_window_get_handle (window);

  /* Private DC? */
  wndclass_style = GetClassLong (hwnd, GCL_STYLE);
  if (wndclass_style & CS_OWNDC)
    {
      GDK_GL_NOTE (MISC, g_message (" -- Private DC"));
      need_release_dc = FALSE;
    }
  else
    {
      GDK_GL_NOTE (MISC, g_message (" -- Common DC"));
      need_release_dc = TRUE;
    }

  /* Get DC. */
  hdc = GetDC (hwnd);
  if (hdc == NULL)
    {
      g_warning ("cannot get DC");
      goto FAIL;
    }

  /*
   * Choose pixel format.
   */

  pfd = *(GDK_GL_CONFIG_PFD (glconfig));
  /* Draw to window */
  pfd.dwFlags &= ~PFD_DRAW_TO_BITMAP;
  pfd.dwFlags |= PFD_DRAW_TO_WINDOW;

  /* Request pfd.cColorBits should exclude alpha bitplanes. */
  pfd.cColorBits = pfd.cRedBits + pfd.cGreenBits + pfd.cBlueBits;

  GDK_GL_NOTE_FUNC_IMPL ("ChoosePixelFormat");

  pixel_format = ChoosePixelFormat (hdc, &pfd);
  if (pixel_format == 0)
    {
      g_warning ("cannot choose pixel format");
      goto FAIL;
    }

  /*
   * Set pixel format.
   */

  GDK_GL_NOTE_FUNC_IMPL ("SetPixelFormat");

  if (!SetPixelFormat (hdc, pixel_format, &pfd))
    {
      g_warning ("cannot set pixel format");
      goto FAIL;
    }

  DescribePixelFormat (hdc, pixel_format, sizeof (pfd), &pfd);

  GDK_GL_NOTE (MISC, g_message (" -- impl->pixel_format = 0x%x", pixel_format));
  GDK_GL_NOTE (MISC, _gdk_win32_gl_print_pfd (&pfd));

  if (need_release_dc)
    {
      /* Release DC. */
      ReleaseDC (hwnd, hdc);
      hdc = NULL;
    }

  /*
   * Instantiate the GdkGLWindowImplWin32 object.
   */

  win32_impl = g_object_new (GDK_TYPE_GL_WINDOW_IMPL_WIN32, NULL);

  win32_impl->hwnd = hwnd;

  win32_impl->pfd = pfd;
  win32_impl->pixel_format = pixel_format;

  win32_impl->glconfig = glconfig;
  g_object_ref (G_OBJECT (win32_impl->glconfig));

  win32_impl->hdc = hdc;
  win32_impl->need_release_dc = need_release_dc;

  win32_impl->is_destroyed = FALSE;

  glwindow->impl = GDK_GL_WINDOW_IMPL(win32_impl);
  glwindow->window = window;
  g_object_add_weak_pointer (G_OBJECT (glwindow->window),
                             (gpointer *) &(glwindow->window));

  return glwindow;

 FAIL:

  /* Release DC. */
  if (need_release_dc && hdc != NULL)
    ReleaseDC (hwnd, hdc);

  return NULL;
}
/*
 * attrib_list is currently unused. This must be set to NULL or empty
 * (first attribute of None). See GLX 1.3 spec.
 */
GdkGLPixmap *
gdk_gl_pixmap_new (GdkGLConfig *glconfig,
                   GdkPixmap   *pixmap,
                   const int   *attrib_list)
{
  GdkGLPixmap *glpixmap;
  GdkGLPixmapImplWin32 *impl;

  gint width, height;
  gint depth;
  GdkPixmap *pixmap_gl = NULL;

  HBITMAP hbitmap_gl;
  HDC hdc_gl = NULL;
  PIXELFORMATDESCRIPTOR pfd;
  int pixel_format;

  HBITMAP hbitmap_gdk;
  HDC hdc_gdk = NULL;

  GDK_GL_NOTE_FUNC ();

  g_return_val_if_fail (GDK_IS_GL_CONFIG_IMPL_WIN32 (glconfig), NULL);
  g_return_val_if_fail (GDK_IS_PIXMAP (pixmap), NULL);

  /*
   * Create offscreen rendering area.
   */

  gdk_drawable_get_size (GDK_DRAWABLE (pixmap), &width, &height);
  depth = gdk_drawable_get_depth (GDK_DRAWABLE (pixmap));

  pixmap_gl = gdk_pixmap_new (NULL, width, height, depth);
  if (pixmap_gl == NULL)
    goto FAIL;

  /*
   * Source (OpenGL) DIB
   */

  hbitmap_gl = (HBITMAP) gdk_win32_drawable_get_handle (GDK_DRAWABLE (pixmap_gl));

  /* Create a memory DC. */
  hdc_gl = CreateCompatibleDC (NULL);
  if (hdc_gl == NULL)
    {
      g_warning ("cannot create a memory DC");
      goto FAIL;
    }

  /* Select the bitmap. */
  if (SelectObject (hdc_gl, hbitmap_gl) == NULL)
    {
      g_warning ("cannot select DIB");
      goto FAIL;
    }

  /*
   * Choose pixel format.
   */

  pfd = *(GDK_GL_CONFIG_PFD (glconfig));
  /* Draw to bitmap */
  pfd.dwFlags &= ~PFD_DRAW_TO_WINDOW;
  pfd.dwFlags |= PFD_DRAW_TO_BITMAP;

  /* Request pfd.cColorBits should exclude alpha bitplanes. */
  pfd.cColorBits = pfd.cRedBits + pfd.cGreenBits + pfd.cBlueBits;

  GDK_GL_NOTE_FUNC_IMPL ("ChoosePixelFormat");

  pixel_format = ChoosePixelFormat (hdc_gl, &pfd);
  if (pixel_format == 0)
    {
      g_warning ("cannot choose pixel format");
      goto FAIL;
    }

  /*
   * Set pixel format.
   */

  GDK_GL_NOTE_FUNC_IMPL ("SetPixelFormat");

  if (!SetPixelFormat (hdc_gl, pixel_format, &pfd))
    {
      g_warning ("cannot set pixel format");
      goto FAIL;
    }

  DescribePixelFormat (hdc_gl, pixel_format, sizeof (pfd), &pfd);

  GDK_GL_NOTE (MISC, g_message (" -- impl->pixel_format = 0x%x", pixel_format));
  GDK_GL_NOTE (MISC, _gdk_win32_gl_print_pfd (&pfd));

  /*
   * Destination (GDK) DIB
   */

  hbitmap_gdk = (HBITMAP) gdk_win32_drawable_get_handle (GDK_DRAWABLE (pixmap));

  /* Create a memory DC. */
  hdc_gdk = CreateCompatibleDC (hdc_gl);
  if (hdc_gdk == NULL)
    {
      g_warning ("cannot create a memory DC");
      goto FAIL;
    }

  /*
   * Instantiate the GdkGLPixmapImplWin32 object.
   */

  glpixmap = g_object_new (GDK_TYPE_GL_PIXMAP_IMPL_WIN32, NULL);
  impl = GDK_GL_PIXMAP_IMPL_WIN32 (glpixmap);

  glpixmap->drawable = GDK_DRAWABLE (pixmap);
  g_object_add_weak_pointer (G_OBJECT (glpixmap->drawable),
                             (gpointer *) &(glpixmap->drawable));

  impl->pixmap_gl = pixmap_gl;

  impl->width = width;
  impl->height = height;

  impl->pfd = pfd;
  impl->pixel_format = pixel_format;

  impl->glconfig = glconfig;
  g_object_ref (G_OBJECT (impl->glconfig));

  impl->hdc_gl = hdc_gl;

  impl->hdc_gdk = hdc_gdk;
  impl->hbitmap_gdk = hbitmap_gdk;

  impl->is_destroyed = FALSE;

  return glpixmap;

 FAIL:

  if (hdc_gdk != NULL)
    DeleteDC (hdc_gdk);

  if (hdc_gl != NULL)
    DeleteDC (hdc_gl);

  if (pixmap_gl != NULL)
    g_object_unref (G_OBJECT (pixmap_gl));

  return NULL;  
}
Exemple #18
0
/**
 * gdk_gl_pixmap_new:
 * @glconfig: a #GdkGLConfig.
 * @pixmap: the #GdkPixmap to be used as the rendering area.
 * @attrib_list: this must be set to NULL or empty (first attribute of None).
 *
 * Creates an off-screen rendering area.
 * attrib_list is currently unused. This must be set to NULL or empty
 * (first attribute of None). See GLX 1.3 spec.
 *
 * Return value: the new #GdkGLPixmap.
 **/
GdkGLPixmap *
gdk_gl_pixmap_new (GdkGLConfig *glconfig,
                   GdkPixmap   *pixmap,
                   const int   *attrib_list)
{
  GdkGLPixmap *glpixmap;
  GdkGLPixmapImplX11 *impl;

  Display *xdisplay;
  XVisualInfo *xvinfo;
  Pixmap xpixmap;
  GLXPixmap glxpixmap;

  Window root_return;
  int x_return, y_return;
  unsigned int width_return, height_return;
  unsigned int border_width_return;
  unsigned int depth_return;

  GdkGL_GLX_MESA_pixmap_colormap *mesa_ext;

  GDK_GL_NOTE_FUNC ();

  g_return_val_if_fail (GDK_IS_GL_CONFIG_IMPL_X11 (glconfig), NULL);
  g_return_val_if_fail (GDK_IS_PIXMAP (pixmap), NULL);

  xdisplay = GDK_GL_CONFIG_XDISPLAY (glconfig);
  xvinfo = GDK_GL_CONFIG_XVINFO (glconfig);

  /*
   * Get X Pixmap.
   */

  xpixmap = GDK_DRAWABLE_XID (GDK_DRAWABLE (pixmap));

  /*
   * Check depth of the X pixmap.
   */

  if (!XGetGeometry (xdisplay, xpixmap,
                     &root_return,
                     &x_return, &y_return,
                     &width_return, &height_return,
                     &border_width_return,
                     &depth_return))
    return NULL;

  if (depth_return != (unsigned int) xvinfo->depth)
    return NULL;

  /*
   * Create GLXPixmap.
   */

  mesa_ext = gdk_gl_get_GLX_MESA_pixmap_colormap (glconfig);
  if (mesa_ext)
    {
      /* If GLX_MESA_pixmap_colormap is supported. */

      GDK_GL_NOTE_FUNC_IMPL ("glXCreateGLXPixmapMESA");

      glxpixmap = mesa_ext->glXCreateGLXPixmapMESA (xdisplay,
                                                    xvinfo,
                                                    xpixmap,
                                                    GDK_GL_CONFIG_XCOLORMAP (glconfig));
    }
  else
    {
      GDK_GL_NOTE_FUNC_IMPL ("glXCreateGLXPixmap");

      glxpixmap = glXCreateGLXPixmap (xdisplay,
                                      xvinfo,
                                      xpixmap);
    }

  if (glxpixmap == None)
    return NULL;

  /*
   * Instantiate the GdkGLPixmapImplX11 object.
   */

  glpixmap = g_object_new (GDK_TYPE_GL_PIXMAP_IMPL_X11, NULL);
  impl = GDK_GL_PIXMAP_IMPL_X11 (glpixmap);

  glpixmap->drawable = GDK_DRAWABLE (pixmap);
  g_object_add_weak_pointer (G_OBJECT (glpixmap->drawable),
                             (gpointer *) &(glpixmap->drawable));

  impl->glxpixmap = glxpixmap;

  impl->glconfig = glconfig;
  g_object_ref (G_OBJECT (impl->glconfig));

  impl->is_destroyed = FALSE;

  return glpixmap;
}