From a02e20a14a44fb75cbf5137917102a5216899ef1 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Mon, 26 Nov 2007 12:07:25 +0000 Subject: [PATCH] 2007-11-26 Emmanuele Bassi * clutter/clutter-actor.c: (clutter_actor_real_show), (clutter_actor_real_hide): Do not set the MAPPED flag on the actor if it is a top-level one (like ClutterStage); the backends are responsible for setting that flag, as it might be the result of an asynchronous operation (e.g. on X11). * clutter/eglnative/clutter-stage-egl.c: (clutter_stage_egl_show), (clutter_stage_egl_hide): Set/unset the CLUTTER_ACTOR_MAPPED flag on show and hide respectively. * clutter/osx/clutter-stage-osx.c: (clutter_stage_osx_show), (clutter_stage_osx_hide): Ditto as above. * clutter/sdl/clutter-stage-sdl.c: (clutter_stage_sdl_show), (clutter_stage_sdl_hide): Ditto as above, plus chain up to the parent class show/hide virtual functions. * clutter/x11/clutter-event-x11.c (event_translate): Use the MapNotify and UnmapNotify events to call the X11 stage map/unmap functions. * clutter/x11/clutter-stage-x11.[ch]: (clutter_stage_x11_set_fullscreen): Set the fullscreen_on_map flag with the fullscreen value. (clutter_stage_x11_map), (clutter_stage_x11_unmap): Set the MAPPED flag on the stage actor and redraw; also, if the fullscreen_on_map flag was set, call clutter_stage_fullscreen() as well. (#648) * tests/Makefile.am: * tests/test-fullscreen.c: Add a fullscreen test case for checking whether fullscreen works on every backend/platform. --- ChangeLog | 38 +++++++ clutter/clutter-actor.c | 13 ++- clutter/eglnative/clutter-stage-egl.c | 8 +- clutter/osx/clutter-stage-osx.c | 4 + clutter/sdl/clutter-stage-sdl.c | 8 +- clutter/x11/clutter-event-x11.c | 154 +++++++++++++++----------- clutter/x11/clutter-stage-x11.c | 74 +++++++++---- clutter/x11/clutter-stage-x11.h | 11 +- tests/Makefile.am | 3 +- tests/test-fullscreen.c | 92 +++++++++++++++ 10 files changed, 301 insertions(+), 104 deletions(-) create mode 100644 tests/test-fullscreen.c diff --git a/ChangeLog b/ChangeLog index 8108d2b57..7cb2aa8f6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,41 @@ +2007-11-26 Emmanuele Bassi + + * clutter/clutter-actor.c: + (clutter_actor_real_show), + (clutter_actor_real_hide): Do not set the MAPPED flag on the actor + if it is a top-level one (like ClutterStage); the backends are + responsible for setting that flag, as it might be the result of an + asynchronous operation (e.g. on X11). + + * clutter/eglnative/clutter-stage-egl.c: + (clutter_stage_egl_show), + (clutter_stage_egl_hide): Set/unset the CLUTTER_ACTOR_MAPPED flag + on show and hide respectively. + + * clutter/osx/clutter-stage-osx.c: + (clutter_stage_osx_show), + (clutter_stage_osx_hide): Ditto as above. + + * clutter/sdl/clutter-stage-sdl.c: + (clutter_stage_sdl_show), + (clutter_stage_sdl_hide): Ditto as above, plus chain up to the + parent class show/hide virtual functions. + + * clutter/x11/clutter-event-x11.c (event_translate): Use the MapNotify + and UnmapNotify events to call the X11 stage map/unmap functions. + + * clutter/x11/clutter-stage-x11.[ch]: + (clutter_stage_x11_set_fullscreen): Set the fullscreen_on_map flag + with the fullscreen value. + + (clutter_stage_x11_map), (clutter_stage_x11_unmap): Set the MAPPED + flag on the stage actor and redraw; also, if the fullscreen_on_map + flag was set, call clutter_stage_fullscreen() as well. (#648) + + * tests/Makefile.am: + * tests/test-fullscreen.c: Add a fullscreen test case for checking + whether fullscreen works on every backend/platform. + 2007-11-23 Emmanuele Bassi * clutter/clutter-actor.c: diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index ae76f8728..12083ca6a 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -233,7 +233,11 @@ clutter_actor_real_show (ClutterActor *self) if (!CLUTTER_ACTOR_IS_REALIZED (self)) clutter_actor_realize (self); - CLUTTER_ACTOR_SET_FLAGS (self, CLUTTER_ACTOR_MAPPED); + /* the mapped flag on the top-level actors is set by the + * per-backend implementation because it might be asynchronous + */ + if (!(CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_IS_TOPLEVEL)) + CLUTTER_ACTOR_SET_FLAGS (self, CLUTTER_ACTOR_MAPPED); if (CLUTTER_ACTOR_IS_VISIBLE (self)) clutter_actor_queue_redraw (self); @@ -286,7 +290,12 @@ clutter_actor_real_hide (ClutterActor *self) { if (CLUTTER_ACTOR_IS_VISIBLE (self)) { - CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_MAPPED); + /* see comment in clutter_actor_real_show() on why we don't set + * the mapped flag on the top-level actors + */ + if (!(CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_IS_TOPLEVEL)) + CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_MAPPED); + clutter_actor_queue_redraw (self); } } diff --git a/clutter/eglnative/clutter-stage-egl.c b/clutter/eglnative/clutter-stage-egl.c index 35b54f3a8..dcad992eb 100644 --- a/clutter/eglnative/clutter-stage-egl.c +++ b/clutter/eglnative/clutter-stage-egl.c @@ -22,9 +22,7 @@ clutter_stage_egl_show (ClutterActor *actor) { ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (actor); - /* we are always shown... */ - - return; + CLUTTER_ACTOR_SET_FLAGS (stage_egl, CLUTTER_ACTOR_MAPPED); } static void @@ -32,9 +30,7 @@ clutter_stage_egl_hide (ClutterActor *actor) { ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (actor); - /* we are always shown... */ - - return; + CLUTTER_ACTOR_UNSET_FLAGS (stage_egl, CLUTTER_ACTOR_MAPPED); } static void diff --git a/clutter/osx/clutter-stage-osx.c b/clutter/osx/clutter-stage-osx.c index 79c6da289..096acbbe6 100644 --- a/clutter/osx/clutter-stage-osx.c +++ b/clutter/osx/clutter-stage-osx.c @@ -322,6 +322,8 @@ clutter_stage_osx_show (ClutterActor *actor) CLUTTER_NOTE (BACKEND, "show"); + CLUTTER_ACTOR_SET_FLAGS (actor, CLUTTER_ACTOR_MAPPED); + if (CLUTTER_ACTOR_CLASS (clutter_stage_osx_parent_class)->show) CLUTTER_ACTOR_CLASS (clutter_stage_osx_parent_class)->show (actor); @@ -347,6 +349,8 @@ clutter_stage_osx_hide (ClutterActor *actor) CLUTTER_OSX_POOL_RELEASE(); + CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_MAPPED); + if (CLUTTER_ACTOR_CLASS (clutter_stage_osx_parent_class)->hide) CLUTTER_ACTOR_CLASS (clutter_stage_osx_parent_class)->hide (actor); } diff --git a/clutter/sdl/clutter-stage-sdl.c b/clutter/sdl/clutter-stage-sdl.c index 92b7d2cf7..893ab92a7 100644 --- a/clutter/sdl/clutter-stage-sdl.c +++ b/clutter/sdl/clutter-stage-sdl.c @@ -22,14 +22,18 @@ G_DEFINE_TYPE (ClutterStageSDL, clutter_stage_sdl, CLUTTER_TYPE_STAGE); static void clutter_stage_sdl_show (ClutterActor *actor) { - ; + CLUTTER_ACTOR_SET_FLAGS (actor, CLUTTER_ACTOR_MAPPED); + + CLUTTER_ACTOR_CLASS (clutter_stage_sdl_parent_class)->show (actor); } static void clutter_stage_sdl_hide (ClutterActor *actor) { /* No way to easily unmap SDL window ? */ - ; + CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_MAPPED); + + CLUTTER_ACTOR_CLASS (clutter_stage_sdl_parent_class)->hide (actor); } static void diff --git a/clutter/x11/clutter-event-x11.c b/clutter/x11/clutter-event-x11.c index da162fb75..b7c8f8ed6 100644 --- a/clutter/x11/clutter-event-x11.c +++ b/clutter/x11/clutter-event-x11.c @@ -233,11 +233,11 @@ translate_key_event (ClutterBackend *backend, event->key.hardware_keycode = xevent->xkey.keycode; /* FIXME: We need to handle other modifiers rather than just shift */ - event->key.keyval - = XKeycodeToKeysym (xevent->xkey.display, - xevent->xkey.keycode, - (event->key.modifier_state & CLUTTER_SHIFT_MASK) - ? 1 : 0); + event->key.keyval = + XKeycodeToKeysym (xevent->xkey.display, + xevent->xkey.keycode, + (event->key.modifier_state & CLUTTER_SHIFT_MASK) ? 1 + : 0); } static gboolean @@ -256,7 +256,7 @@ handle_wm_protocols_event (ClutterBackendX11 *backend_x11, * we relay the event to the application and we let it * handle the request */ - CLUTTER_NOTE (EVENT, "delete window:\twindow: %ld", + CLUTTER_NOTE (EVENT, "delete window:\txid: %ld", xevent->xclient.window); set_user_time (backend_x11, @@ -380,73 +380,89 @@ event_translate (ClutterBackend *backend, switch (xevent->type) { case ConfigureNotify: - if (xevent->xconfigure.width - != clutter_actor_get_width (CLUTTER_ACTOR (stage)) - || - xevent->xconfigure.height - != clutter_actor_get_height (CLUTTER_ACTOR (stage))) - clutter_actor_set_size (CLUTTER_ACTOR (stage), - xevent->xconfigure.width, - xevent->xconfigure.height); + { + guint stage_width, stage_height; + + clutter_actor_get_size (CLUTTER_ACTOR (stage), + &stage_width, + &stage_height); + + if (xevent->xconfigure.width != stage_width || + xevent->xconfigure.height != stage_height) + { + clutter_actor_set_size (CLUTTER_ACTOR (stage), + xevent->xconfigure.width, + xevent->xconfigure.height); + } + } res = FALSE; break; + case PropertyNotify: - { - if (xevent->xproperty.atom == backend_x11->atom_NET_WM_STATE) - { - Atom type; - gint format; - gulong nitems, bytes_after; - guchar *data = NULL; - Atom *atoms = NULL; - gulong i; - gboolean fullscreen_set = FALSE; + if (xevent->xproperty.atom == backend_x11->atom_NET_WM_STATE) + { + Atom type; + gint format; + gulong n_items, bytes_after; + guchar *data = NULL; + gboolean fullscreen_set = FALSE; - clutter_x11_trap_x_errors (); - XGetWindowProperty (backend_x11->xdpy, - stage_xwindow, - backend_x11->atom_NET_WM_STATE, - 0, G_MAXLONG, - False, XA_ATOM, - &type, &format, &nitems, - &bytes_after, &data); - clutter_x11_untrap_x_errors (); + clutter_x11_trap_x_errors (); + XGetWindowProperty (backend_x11->xdpy, stage_xwindow, + backend_x11->atom_NET_WM_STATE, + 0, G_MAXLONG, + False, XA_ATOM, + &type, &format, &n_items, + &bytes_after, &data); + clutter_x11_untrap_x_errors (); - if (type != None && data != NULL) - { - atoms = (Atom *)data; + if (type != None && data != NULL) + { + Atom *atoms = (Atom *) data; + gulong i; + gboolean is_fullscreen = FALSE; - i = 0; - while (i < nitems) - { - if (atoms[i] == backend_x11->atom_NET_WM_STATE_FULLSCREEN) - fullscreen_set = TRUE; - i++; - } + for (i = 0; i < n_items; i++) + { + if (atoms[i] == backend_x11->atom_NET_WM_STATE_FULLSCREEN) + fullscreen_set = TRUE; + } - if (fullscreen_set - != !!(stage_x11->state & CLUTTER_STAGE_STATE_FULLSCREEN)) - { - if (fullscreen_set) - stage_x11->state |= CLUTTER_STAGE_STATE_FULLSCREEN; - else - stage_x11->state &= ~CLUTTER_STAGE_STATE_FULLSCREEN; + is_fullscreen = + (stage_x11->state & CLUTTER_STAGE_STATE_FULLSCREEN); - event->type = CLUTTER_STAGE_STATE; - event->stage_state.changed_mask - = CLUTTER_STAGE_STATE_FULLSCREEN; - event->stage_state.new_state = stage_x11->state; - } - else - res = FALSE; + if (fullscreen_set != is_fullscreen) + { + if (fullscreen_set) + stage_x11->state |= CLUTTER_STAGE_STATE_FULLSCREEN; + else + stage_x11->state &= ~CLUTTER_STAGE_STATE_FULLSCREEN; - XFree (data); - } - } - else - res = FALSE; - } + event->type = CLUTTER_STAGE_STATE; + event->stage_state.changed_mask = + CLUTTER_STAGE_STATE_FULLSCREEN; + event->stage_state.new_state = stage_x11->state; + } + else + res = FALSE; + + XFree (data); + } + else + res = FALSE; + } break; + + case MapNotify: + clutter_stage_x11_map (stage_x11); + res = FALSE; + break; + + case UnmapNotify: + clutter_stage_x11_unmap (stage_x11); + res = FALSE; + break; + case FocusIn: if (!(stage_x11->state & CLUTTER_STAGE_STATE_ACTIVATED)) { @@ -460,6 +476,7 @@ event_translate (ClutterBackend *backend, else res = FALSE; break; + case FocusOut: if (stage_x11->state & CLUTTER_STAGE_STATE_ACTIVATED) { @@ -472,6 +489,7 @@ event_translate (ClutterBackend *backend, else res = FALSE; break; + case Expose: { XEvent foo_xev; @@ -489,15 +507,18 @@ event_translate (ClutterBackend *backend, res = FALSE; } break; + case KeyPress: event->type = CLUTTER_KEY_PRESS; translate_key_event (backend, event, xevent); set_user_time (backend_x11, &xwindow, xevent->xkey.time); break; + case KeyRelease: event->type = CLUTTER_KEY_RELEASE; translate_key_event (backend, event, xevent); break; + case ButtonPress: switch (xevent->xbutton.button) { @@ -535,6 +556,7 @@ event_translate (ClutterBackend *backend, set_user_time (backend_x11, &xwindow, event->button.time); break; + case ButtonRelease: /* scroll events don't have a corresponding release */ if (xevent->xbutton.button == 4 || @@ -553,6 +575,7 @@ event_translate (ClutterBackend *backend, event->button.modifier_state = xevent->xbutton.state; event->button.button = xevent->xbutton.button; break; + case MotionNotify: event->motion.type = event->type = CLUTTER_MOTION; event->motion.time = xevent->xmotion.time; @@ -560,11 +583,13 @@ event_translate (ClutterBackend *backend, event->motion.y = xevent->xmotion.y; event->motion.modifier_state = xevent->xmotion.state; break; + case DestroyNotify: - CLUTTER_NOTE (EVENT, "destroy notify:\twindow: %ld", + CLUTTER_NOTE (EVENT, "destroy notify:\txid: %ld", xevent->xdestroywindow.window); event->type = event->any.type = CLUTTER_DESTROY_NOTIFY; break; + case ClientMessage: CLUTTER_NOTE (EVENT, "client message"); @@ -578,6 +603,7 @@ event_translate (ClutterBackend *backend, event->type = event->any.type = CLUTTER_DELETE; } break; + default: /* ignore every other event */ res = FALSE; diff --git a/clutter/x11/clutter-stage-x11.c b/clutter/x11/clutter-stage-x11.c index d79d24a2d..f891b148d 100644 --- a/clutter/x11/clutter-stage-x11.c +++ b/clutter/x11/clutter-stage-x11.c @@ -94,10 +94,10 @@ clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11) if (!resize) { - size_hints->max_width - = size_hints->min_width = stage_x11->xwin_width; - size_hints->max_height - = size_hints->min_height = stage_x11->xwin_height; + size_hints->max_width = size_hints->min_width = + stage_x11->xwin_width; + size_hints->max_height = size_hints->min_height = + stage_x11->xwin_height; size_hints->flags = PMinSize|PMaxSize; } @@ -112,19 +112,18 @@ clutter_stage_x11_show (ClutterActor *actor) { ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (actor); - /* Chain up to set mapped flags */ - CLUTTER_ACTOR_CLASS (clutter_stage_x11_parent_class)->show(actor); - if (stage_x11->xwin) { /* Fire off a redraw to avoid flicker on first map. * Appears not to work perfectly on intel drivers at least. */ clutter_redraw(); + XSync (stage_x11->xdpy, FALSE); XMapWindow (stage_x11->xdpy, stage_x11->xwin); } + /* chain up */ CLUTTER_ACTOR_CLASS (clutter_stage_x11_parent_class)->show (actor); } @@ -136,6 +135,7 @@ clutter_stage_x11_hide (ClutterActor *actor) if (stage_x11->xwin) XUnmapWindow (stage_x11->xdpy, stage_x11->xwin); + /* chain up */ CLUTTER_ACTOR_CLASS (clutter_stage_x11_parent_class)->hide (actor); } @@ -219,7 +219,12 @@ clutter_stage_x11_set_fullscreen (ClutterStage *stage, { if (stage_x11->xwin != None) { - if (!CLUTTER_ACTOR_IS_MAPPED(CLUTTER_ACTOR (stage_x11))) + /* if the actor is not mapped we resize the stage window to match + * the size of the screen; this is useful for e.g. EGLX to avoid + * a resize when calling clutter_stage_fullscreen() before showing + * the stage + */ + if (!CLUTTER_ACTOR_IS_MAPPED (stage_x11)) { gint width, height; @@ -228,14 +233,13 @@ clutter_stage_x11_set_fullscreen (ClutterStage *stage, clutter_actor_set_size (CLUTTER_ACTOR (stage_x11), width, height); + /* FIXME: This wont work if we support more states */ - XChangeProperty - (stage_x11->xdpy, - stage_x11->xwin, - backend_x11->atom_NET_WM_STATE, XA_ATOM, 32, - PropModeReplace, - (unsigned char *)&backend_x11->atom_NET_WM_STATE_FULLSCREEN, - 1); + XChangeProperty (stage_x11->xdpy, + stage_x11->xwin, + backend_x11->atom_NET_WM_STATE, XA_ATOM, 32, + PropModeReplace, + (unsigned char *) &backend_x11->atom_NET_WM_STATE_FULLSCREEN, 1); } else { @@ -247,18 +251,19 @@ clutter_stage_x11_set_fullscreen (ClutterStage *stage, else clutter_stage_set_user_resizable (stage, TRUE); - send_wmspec_change_state(backend_x11, - stage_x11->xwin, + send_wmspec_change_state(backend_x11, stage_x11->xwin, backend_x11->atom_NET_WM_STATE_FULLSCREEN, TRUE); } + + stage_x11->fullscreen_on_map = TRUE; } } else { if (stage_x11->xwin != None) { - if (!CLUTTER_ACTOR_IS_MAPPED(CLUTTER_ACTOR (stage_x11))) + if (!CLUTTER_ACTOR_IS_MAPPED (stage_x11)) { /* FIXME: This wont work if we support more states */ XDeleteProperty (stage_x11->xdpy, @@ -280,10 +285,12 @@ clutter_stage_x11_set_fullscreen (ClutterStage *stage, was_resizeable = FALSE; } + + stage_x11->fullscreen_on_map = FALSE; } } - CLUTTER_SET_PRIVATE_FLAGS(stage, CLUTTER_ACTOR_SYNC_MATRICES); + CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_SYNC_MATRICES); } static void @@ -301,9 +308,7 @@ clutter_stage_x11_set_cursor_visible (ClutterStage *stage, if (show_cursor) { -#if 0 /* HAVE_XFIXES - borked on fiesty at least so disabled until further - * investigation. - */ +#if 0 /* HAVE_XFIXES */ XFixesShowCursor (stage_x11->xdpy, stage_x11->xwin); #else XUndefineCursor (stage_x11->xdpy, stage_x11->xwin); @@ -311,7 +316,7 @@ clutter_stage_x11_set_cursor_visible (ClutterStage *stage, } else { -#if 0 /* HAVE_XFIXES - borked */ +#if 0 /* HAVE_XFIXES */ XFixesHideCursor (stage_x11->xdpy, stage_x11->xwin); #else XColor col; @@ -420,8 +425,9 @@ clutter_stage_x11_init (ClutterStageX11 *stage) stage->xvisinfo = None; stage->is_foreign_xwin = FALSE; + stage->fullscreen_on_map = FALSE; - CLUTTER_SET_PRIVATE_FLAGS(stage, CLUTTER_ACTOR_SYNC_MATRICES); + CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_SYNC_MATRICES); } /** @@ -522,3 +528,23 @@ clutter_x11_set_stage_foreign (ClutterStage *stage, return TRUE; } + +void +clutter_stage_x11_map (ClutterStageX11 *stage_x11) +{ + CLUTTER_ACTOR_SET_FLAGS (stage_x11, CLUTTER_ACTOR_MAPPED); + + if (stage_x11->fullscreen_on_map) + clutter_stage_fullscreen (CLUTTER_STAGE (stage_x11)); + else + clutter_stage_unfullscreen (CLUTTER_STAGE (stage_x11)); + + clutter_actor_queue_redraw (CLUTTER_ACTOR (stage_x11)); +} + +void +clutter_stage_x11_unmap (ClutterStageX11 *stage_x11) +{ + CLUTTER_ACTOR_UNSET_FLAGS (stage_x11, CLUTTER_ACTOR_MAPPED); +} + diff --git a/clutter/x11/clutter-stage-x11.h b/clutter/x11/clutter-stage-x11.h index 194d6e9cd..9a00741d8 100644 --- a/clutter/x11/clutter-stage-x11.h +++ b/clutter/x11/clutter-stage-x11.h @@ -45,7 +45,8 @@ struct _ClutterStageX11 { ClutterStage parent_instance; - int is_foreign_xwin :1; + guint is_foreign_xwin : 1; + guint fullscreen_on_map : 1; Display *xdpy; Window xwin_root; @@ -68,11 +69,11 @@ struct _ClutterStageX11Class GType clutter_stage_x11_get_type (void) G_GNUC_CONST; /* Private to subclasses */ -void -clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11); +void clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11); +void clutter_stage_x11_set_wm_protocols (ClutterStageX11 *stage_x11); -void -clutter_stage_x11_set_wm_protocols (ClutterStageX11 *stage_x11); +void clutter_stage_x11_map (ClutterStageX11 *stage_x11); +void clutter_stage_x11_unmap (ClutterStageX11 *stage_x11); G_END_DECLS diff --git a/tests/Makefile.am b/tests/Makefile.am index 1fa4ec034..ae9a05741 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -2,7 +2,7 @@ noinst_PROGRAMS = test-textures test-events test-offscreen test-scale \ test-actors test-behave test-text test-entry test-project \ test-boxes test-perspective test-rotate test-depth \ test-threads test-timeline test-score test-script \ - test-model test-grab test-effects + test-model test-grab test-effects test-fullscreen INCLUDES = -I$(top_srcdir)/ LDADD = $(top_builddir)/clutter/libclutter-@CLUTTER_FLAVOUR@-@CLUTTER_MAJORMINOR@.la @@ -29,5 +29,6 @@ test_score_SOURCES = test-score.c test_script_SOURCES = test-script.c test_model_SOURCES = test-model.c test_effects_SOURCES = test-effects.c +test_fullscreen_SOURCES = test-fullscreen.c EXTRA_DIST = redhand.png test-script.json diff --git a/tests/test-fullscreen.c b/tests/test-fullscreen.c new file mode 100644 index 000000000..a6f6a0488 --- /dev/null +++ b/tests/test-fullscreen.c @@ -0,0 +1,92 @@ +#include +#include + +enum +{ + START, + HIDE, + SHOW, + DONE +}; + +static int state = START; + +static void +on_fullscreen (ClutterStage *stage) +{ + g_debug ("fullscreen set, size: %dx%d, mapped: %s", + clutter_actor_get_width (CLUTTER_ACTOR (stage)), + clutter_actor_get_height (CLUTTER_ACTOR (stage)), + CLUTTER_ACTOR_IS_MAPPED (stage) ? "true" : "false"); +} + +static void +on_unfullscreen (ClutterStage *stage) +{ + g_debug ("fullscreen unset, size: %dx%d, mapped: %s", + clutter_actor_get_width (CLUTTER_ACTOR (stage)), + clutter_actor_get_height (CLUTTER_ACTOR (stage)), + CLUTTER_ACTOR_IS_MAPPED (stage) ? "true" : "false"); +} + +static gboolean +toggle_fullscreen (gpointer dummy) +{ + ClutterActor *stage = clutter_stage_get_default (); + gboolean is_fullscreen = FALSE; + + g_object_get (G_OBJECT (stage), "fullscreen", &is_fullscreen, NULL); + + switch (state) + { + case START: + g_debug ("start: is_fullscreen := %s", is_fullscreen ? "true" : "false"); + clutter_actor_hide (stage); + state = HIDE; + return TRUE; + + case HIDE: + g_debug ("hide: is_fullscreen := %s", is_fullscreen ? "true" : "false"); + clutter_actor_show (stage); + state = SHOW; + return TRUE; + + case SHOW: + g_debug ("show: is_fullscreen := %s", is_fullscreen ? "true" : "false"); + clutter_stage_unfullscreen (CLUTTER_STAGE (stage)); + state = DONE; + return TRUE; + + case DONE: + g_debug ("done: is_fullscreen := %s", is_fullscreen ? "true" : "false"); + clutter_main_quit (); + break; + } + + return FALSE; +} + +int +main (int argc, char *argv[]) +{ + ClutterActor *stage; + + clutter_init (&argc, &argv); + + stage = clutter_stage_get_default (); + g_signal_connect (stage, + "fullscreen", G_CALLBACK (on_fullscreen), + NULL); + g_signal_connect (stage, + "unfullscreen", G_CALLBACK (on_unfullscreen), + NULL); + + clutter_stage_fullscreen (CLUTTER_STAGE (stage)); + clutter_actor_show (stage); + + g_timeout_add (1000, toggle_fullscreen, NULL); + + clutter_main (); + + return EXIT_SUCCESS; +}