mutter/clutter/glx/clutter-stage-glx.c
Robert Bragg 15d7a86621 [backends] Remove the idea of offscreen stages from all backends
The only backend that tried to implement offscreen stages was the GLX backend
and even this has apparently be broken for some time without anyone noticing.

The property still remains and since the property already clearly states that
it may not work I don't expect anyone to notice.

This simplifies quite a bit of the GLX code which is very desireable from the
POV that we want to start migrating window system code down to Cogl and the
simpler the code is the more straight forward this work will be.

In the future when Cogl has a nicely designed API for framebuffer objects then
re-implementing offscreen stages cleanly for *all* backends should be quite
straightforward.
2009-10-16 18:58:47 +01:00

220 lines
6.7 KiB
C

/* Clutter.
* An OpenGL based 'interactive canvas' library.
* Authored By Matthew Allum <mallum@openedhand.com>
* Copyright (C) 2006-2007 OpenedHand
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "clutter-backend-glx.h"
#include "clutter-stage-glx.h"
#include "clutter-glx.h"
#include "../clutter-main.h"
#include "../clutter-feature.h"
#include "../clutter-color.h"
#include "../clutter-util.h"
#include "../clutter-event.h"
#include "../clutter-enum-types.h"
#include "../clutter-private.h"
#include "../clutter-debug.h"
#include "../clutter-units.h"
#include "../clutter-shader.h"
#include "../clutter-group.h"
#include "../clutter-container.h"
#include "../clutter-stage.h"
#include "../clutter-stage-window.h"
#include "cogl/cogl.h"
#include <GL/glx.h>
#include <GL/gl.h>
static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface);
static ClutterStageWindowIface *clutter_stage_glx_parent_iface = NULL;
G_DEFINE_TYPE_WITH_CODE (ClutterStageGLX,
clutter_stage_glx,
CLUTTER_TYPE_STAGE_X11,
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW,
clutter_stage_window_iface_init));
static void
clutter_stage_glx_unrealize (ClutterStageWindow *stage_window)
{
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
/* Note unrealize should free up any backend stage related resources */
CLUTTER_NOTE (BACKEND, "Unrealizing stage");
clutter_x11_trap_x_errors ();
if (!stage_x11->is_foreign_xwin && stage_x11->xwin != None)
{
XDestroyWindow (stage_x11->xdpy, stage_x11->xwin);
stage_x11->xwin = None;
}
else
stage_x11->xwin = None;
if (stage_x11->xvisinfo != None)
{
XFree (stage_x11->xvisinfo);
stage_x11->xvisinfo = None;
}
XSync (stage_x11->xdpy, False);
clutter_x11_untrap_x_errors ();
CLUTTER_MARK ();
}
static gboolean
clutter_stage_glx_realize (ClutterStageWindow *stage_window)
{
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (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);
stage_x11->xvisinfo = clutter_backend_x11_get_visual_info (backend_x11);
if (stage_x11->xvisinfo == None)
{
g_critical ("Unable to find suitable GL visual.");
return FALSE;
}
if (stage_x11->xwin == None)
{
XSetWindowAttributes xattr;
unsigned long mask;
CLUTTER_NOTE (MISC, "Creating stage X window");
/* window attributes */
xattr.background_pixel = WhitePixel (stage_x11->xdpy,
stage_x11->xscreen);
xattr.border_pixel = 0;
xattr.colormap = XCreateColormap (stage_x11->xdpy,
stage_x11->xwin_root,
stage_x11->xvisinfo->visual,
AllocNone);
mask = CWBorderPixel | CWColormap;
stage_x11->xwin = XCreateWindow (stage_x11->xdpy,
stage_x11->xwin_root,
0, 0,
stage_x11->xwin_width,
stage_x11->xwin_height,
0,
stage_x11->xvisinfo->depth,
InputOutput,
stage_x11->xvisinfo->visual,
mask, &xattr);
}
if (clutter_x11_has_event_retrieval())
{
if (clutter_x11_has_xinput())
{
XSelectInput (stage_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 (stage_x11->xdpy, stage_x11->xwin,
StructureNotifyMask |
FocusChangeMask |
ExposureMask |
PointerMotionMask |
KeyPressMask | KeyReleaseMask |
ButtonPressMask | ButtonReleaseMask |
EnterWindowMask | LeaveWindowMask |
PropertyChangeMask);
}
/* no user resize.. */
clutter_stage_x11_fix_window_size (stage_x11, -1, -1);
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);
}
static void
clutter_stage_glx_dispose (GObject *gobject)
{
G_OBJECT_CLASS (clutter_stage_glx_parent_class)->dispose (gobject);
}
static void
clutter_stage_glx_class_init (ClutterStageGLXClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->dispose = clutter_stage_glx_dispose;
}
static void
clutter_stage_glx_init (ClutterStageGLX *stage)
{
}
static void
clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
{
clutter_stage_glx_parent_iface = g_type_interface_peek_parent (iface);
iface->realize = clutter_stage_glx_realize;
iface->unrealize = clutter_stage_glx_unrealize;
/* the rest is inherited from ClutterStageX11 */
}