diff --git a/ChangeLog b/ChangeLog index efa1a162c..6cd9e06e9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2008-09-23 Tomas Frydrych + + * clutter/clutter-main.c: + * clutter/clutter-main.h: + * clutter/clutter-private.h: + * clutter/x11/clutter-backend-x11.c: + (clutter_get_option_group_without_init): + Function to obtain clutter option group without opening display + (for use with foreign display and gtk_clutter_init). Bug 1033. + + Stripped trailing whitespace. + 2008-09-22 Neil Roberts Bug 856 - Teardown sequence is borked diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c index ea0af7405..a6e032855 100644 --- a/clutter/clutter-main.c +++ b/clutter/clutter-main.c @@ -287,14 +287,14 @@ _clutter_id_to_color (guint id, ClutterColor *col) ctx = clutter_context_get_default (); /* compute the numbers we'll store in the components */ - red = (id >> (ctx->fb_g_mask_used+ctx->fb_b_mask_used)) + red = (id >> (ctx->fb_g_mask_used+ctx->fb_b_mask_used)) & (0xff >> (8-ctx->fb_r_mask_used)); green = (id >> ctx->fb_b_mask_used) & (0xff >> (8-ctx->fb_g_mask_used)); blue = (id) & (0xff >> (8-ctx->fb_b_mask_used)); /* shift left bits a bit and add one, this circumvents * at least some potential rounding errors in GL/GLES - * driver / hw implementation. + * driver / hw implementation. */ if (ctx->fb_r_mask_used != ctx->fb_r_mask) red = red * 2 + 1; @@ -303,7 +303,7 @@ _clutter_id_to_color (guint id, ClutterColor *col) if (ctx->fb_b_mask_used != ctx->fb_b_mask) blue = blue * 2 + 1; - /* shift up to be full 8bit values */ + /* shift up to be full 8bit values */ red = (red << (8 - ctx->fb_r_mask)) | (0xff >> (ctx->fb_r_mask + 1)); green = (green << (8 - ctx->fb_g_mask)) | (0xff >> (ctx->fb_g_mask + 1)); blue = (blue << (8 - ctx->fb_b_mask)) | (0xff >> (ctx->fb_b_mask + 1)); @@ -314,8 +314,8 @@ _clutter_id_to_color (guint id, ClutterColor *col) col->alpha = 0xff; } -guint -_clutter_pixel_to_id (guchar pixel[4]) +guint +_clutter_pixel_to_id (guchar pixel[4]) { ClutterMainContext *ctx; gint red, green, blue; @@ -333,12 +333,12 @@ _clutter_pixel_to_id (guchar pixel[4]) /* divide potentially by two if 'fuzzy' */ red = red >> (ctx->fb_r_mask - ctx->fb_r_mask_used); green = green >> (ctx->fb_g_mask - ctx->fb_g_mask_used); - blue = blue >> (ctx->fb_b_mask - ctx->fb_b_mask_used); + blue = blue >> (ctx->fb_b_mask - ctx->fb_b_mask_used); /* combine the correct per component values into the final id */ - id = blue + (green << ctx->fb_b_mask_used) + id = blue + (green << ctx->fb_b_mask_used) + (red << (ctx->fb_b_mask_used + ctx->fb_g_mask_used)); - + return id; } @@ -353,7 +353,7 @@ _clutter_do_pick (ClutterStage *stage, GLint viewport[4]; ClutterColor white = { 0xff, 0xff, 0xff, 0xff }; guint32 id; - + context = clutter_context_get_default (); _clutter_backend_ensure_context (context->backend, stage); @@ -956,7 +956,6 @@ clutter_context_get_default (void) if (G_UNLIKELY(!ClutterCntx)) { ClutterMainContext *ctx; - gdouble resolution; ClutterCntx = ctx = g_new0 (ClutterMainContext, 1); ctx->backend = g_object_new (_clutter_backend_impl_get_type (), NULL); @@ -968,13 +967,6 @@ clutter_context_get_default (void) ctx->timer = g_timer_new (); g_timer_start (ctx->timer); #endif - - ctx->font_map = PANGO_CLUTTER_FONT_MAP (pango_clutter_font_map_new ()); - - resolution = clutter_backend_get_resolution (ctx->backend); - pango_clutter_font_map_set_resolution (ctx->font_map, resolution); - - pango_clutter_font_map_set_use_mipmapping (ctx->font_map, TRUE); } return ClutterCntx; @@ -1044,11 +1036,42 @@ clutter_init_real (GError **error) { ClutterMainContext *ctx; ClutterActor *stage; + gdouble resolution; + ClutterBackend *backend; /* Note, creates backend if not already existing, though parse args will * have likely created it */ ctx = clutter_context_get_default (); + backend = ctx->backend; + + if (!ctx->options_parsed) + { + g_set_error (error, CLUTTER_INIT_ERROR, + CLUTTER_INIT_ERROR_INTERNAL, + "When using clutter_get_option_group_without_init() " + "you must parse options before calling clutter_init()"); + + return CLUTTER_INIT_ERROR_INTERNAL; + } + + /* + * Call backend post parse hooks. + */ + if (CLUTTER_BACKEND_GET_CLASS (backend)->post_parse) + if (!CLUTTER_BACKEND_GET_CLASS (backend)->post_parse (backend, error)) + return CLUTTER_INIT_ERROR_BACKEND; + + /* + * Resolution requires display to be open, so can only be queried after + * the post_parse hooks run. + */ + ctx->font_map = PANGO_CLUTTER_FONT_MAP (pango_clutter_font_map_new ()); + + resolution = clutter_backend_get_resolution (ctx->backend); + pango_clutter_font_map_set_resolution (ctx->font_map, resolution); + + pango_clutter_font_map_set_use_mipmapping (ctx->font_map, TRUE); /* Stage will give us a GL Context etc */ stage = clutter_stage_get_default (); @@ -1078,7 +1101,7 @@ clutter_init_real (GError **error) return CLUTTER_INIT_ERROR_INTERNAL; } - /* Now we can safely assume we have a valid GL context and can + /* Now we can safely assume we have a valid GL context and can * start issueing cogl commands */ @@ -1108,6 +1131,7 @@ clutter_init_real (GError **error) clutter_stage_set_title (CLUTTER_STAGE (stage), g_get_prgname ()); clutter_is_initialized = TRUE; + ctx->is_initialized = TRUE; return CLUTTER_INIT_SUCCESS; } @@ -1144,7 +1168,7 @@ pre_parse_hook (GOptionContext *context, if (clutter_is_initialized) return TRUE; - + if (setlocale (LC_ALL, "") == NULL) g_warning ("Locale not supported by C library.\n" "Using the fallback 'C' locale."); @@ -1197,7 +1221,6 @@ post_parse_hook (GOptionContext *context, { ClutterMainContext *clutter_context; ClutterBackend *backend; - gboolean retval = FALSE; if (clutter_is_initialized) return TRUE; @@ -1216,16 +1239,16 @@ post_parse_hook (GOptionContext *context, } clutter_context->frame_rate = clutter_default_fps; + clutter_context->options_parsed = TRUE; - if (CLUTTER_BACKEND_GET_CLASS (backend)->post_parse) - retval = CLUTTER_BACKEND_GET_CLASS (backend)->post_parse (backend, error); - else - retval = TRUE; + /* + * If not asked to defer display setup, call clutter_init_real(), + * which in turn calls the backend post parse hooks. + */ + if (!clutter_context->defer_display_setup) + return clutter_init_real (error); - if (retval) - clutter_init_real (error); - - return retval; + return TRUE; } /** @@ -1265,6 +1288,8 @@ clutter_get_option_group (void) ClutterMainContext *context; GOptionGroup *group; + clutter_base_init (); + context = clutter_context_get_default (); group = g_option_group_new ("clutter", @@ -1282,6 +1307,39 @@ clutter_get_option_group (void) return group; } +/** + * clutter_get_option_group_without_init: + * + * Returns a #GOptionGroup for the command line arguments recognized + * by Clutter. You should add this group to your #GOptionContext with + * g_option_context_add_group(), if you are using g_option_context_parse() + * to parse your commandline arguments. Unlike clutter_get_option_group(), + * calling g_option_context_parse() with the #GOptionGroup returned by this + * function requires a subsequent explicit call to clutter_init(); use this + * function when needing to set foreign display connection with + * clutter_x11_set_display(), or with gtk_clutter_init(). + * + * Return value: a #GOptionGroup for the commandline arguments + * recognized by Clutter + * + * Since: 0.8.2 + */ +GOptionGroup * +clutter_get_option_group_without_init (void) +{ + ClutterMainContext *context; + GOptionGroup *group; + + clutter_base_init (); + + context = clutter_context_get_default (); + context->defer_display_setup = TRUE; + + group = clutter_get_option_group (); + + return group; +} + /** * clutter_init_with_args: * @argc: a pointer to the number of command line arguments @@ -1321,41 +1379,49 @@ clutter_init_with_args (int *argc, GOptionContext *context; GOptionGroup *group; gboolean res; + ClutterMainContext *ctx; if (clutter_is_initialized) return CLUTTER_INIT_SUCCESS; clutter_base_init (); - if (argc && *argc > 0 && *argv) - g_set_prgname ((*argv)[0]); + ctx = clutter_context_get_default (); - group = clutter_get_option_group (); - context = g_option_context_new (parameter_string); - - g_option_context_add_group (context, group); - - if (entries) - g_option_context_add_main_entries (context, entries, translation_domain); - - res = g_option_context_parse (context, argc, argv, error); - g_option_context_free (context); - - /* if res is FALSE, the error is filled for - * us by g_option_context_parse() - */ - if (!res) + if (!ctx->defer_display_setup) { - /* if there has been an error in the initialization, the - * error id will be preserved inside the GError code - */ - if (error && *error) - return (*error)->code; - else - return CLUTTER_INIT_ERROR_INTERNAL; - } + if (argc && *argc > 0 && *argv) + g_set_prgname ((*argv)[0]); - return CLUTTER_INIT_SUCCESS; + group = clutter_get_option_group (); + context = g_option_context_new (parameter_string); + + g_option_context_add_group (context, group); + + if (entries) + g_option_context_add_main_entries (context, entries, translation_domain); + + res = g_option_context_parse (context, argc, argv, error); + g_option_context_free (context); + + /* if res is FALSE, the error is filled for + * us by g_option_context_parse() + */ + if (!res) + { + /* if there has been an error in the initialization, the + * error id will be preserved inside the GError code + */ + if (error && *error) + return (*error)->code; + else + return CLUTTER_INIT_ERROR_INTERNAL; + } + + return CLUTTER_INIT_SUCCESS; + } + else + return clutter_init_real (error); } static gboolean @@ -1382,10 +1448,10 @@ clutter_parse_args (int *argc, if (!g_option_context_parse (option_context, argc, argv, &error)) { if (error) - { - g_warning ("%s", error->message); - g_error_free (error); - } + { + g_warning ("%s", error->message); + g_error_free (error); + } ret = FALSE; } @@ -1411,24 +1477,34 @@ ClutterInitError clutter_init (int *argc, char ***argv) { + ClutterMainContext *ctx; + GError *error = NULL; + if (clutter_is_initialized) return CLUTTER_INIT_SUCCESS; clutter_base_init (); - if (argc && *argc > 0 && *argv) - g_set_prgname ((*argv)[0]); + ctx = clutter_context_get_default (); - /* parse_args will trigger backend creation and things like - * DISPLAY connection etc. - */ - if (clutter_parse_args (argc, argv) == FALSE) + if (!ctx->defer_display_setup) { - CLUTTER_NOTE (MISC, "failed to parse arguments."); - return CLUTTER_INIT_ERROR_INTERNAL; - } + if (argc && *argc > 0 && *argv) + g_set_prgname ((*argv)[0]); - return CLUTTER_INIT_SUCCESS; + /* parse_args will trigger backend creation and things like + * DISPLAY connection etc. + */ + if (clutter_parse_args (argc, argv) == FALSE) + { + CLUTTER_NOTE (MISC, "failed to parse arguments."); + return CLUTTER_INIT_ERROR_INTERNAL; + } + + return CLUTTER_INIT_SUCCESS; + } + else + return clutter_init_real (&error); } gboolean @@ -1495,7 +1571,7 @@ event_click_count_generate (ClutterEvent *event) } /* store time and position for this click for comparison with - * next event + * next event */ previous_time = event->button.time; previous_x = event->button.x; @@ -1702,7 +1778,7 @@ generate_enter_leave_events (ClutterEvent *event) if (last_actor && last_actor != motion_current_actor) { - g_signal_handlers_disconnect_by_func + g_signal_handlers_disconnect_by_func (last_actor, G_CALLBACK (unset_motion_last_actor), event->motion.device); @@ -1774,7 +1850,7 @@ clutter_do_event (ClutterEvent *event) else clutter_actor_destroy (stage); } - + break; case CLUTTER_KEY_PRESS: @@ -1850,13 +1926,13 @@ clutter_do_event (ClutterEvent *event) /* global grabs */ if (context->pointer_grab_actor != NULL) { - clutter_actor_event (context->pointer_grab_actor, + clutter_actor_event (context->pointer_grab_actor, event, FALSE); break; } else if (device != NULL && device->pointer_grab_actor != NULL) { - clutter_actor_event (device->pointer_grab_actor, + clutter_actor_event (device->pointer_grab_actor, event, FALSE); break; } @@ -2063,7 +2139,7 @@ on_pointer_grab_weak_notify (gpointer data, { ClutterInputDevice *dev = (ClutterInputDevice *)data; ClutterMainContext *context; - + context = clutter_context_get_default (); if (dev) @@ -2368,7 +2444,7 @@ clutter_set_motion_events_frequency (guint frequency) * renderer. This will free up some memory and GL texture * resources. The cache will be automatically refilled as more text is * drawn. - * + * * Since: 0.8 */ void @@ -2417,7 +2493,7 @@ clutter_get_use_mipmapped_text (void) if (font_map) return pango_clutter_font_map_get_use_mipmapping (font_map); - return FALSE; + return FALSE; } /** @@ -2439,8 +2515,8 @@ clutter_get_input_device_for_id (gint id) context = clutter_context_get_default (); - for (item = context->input_devices; - item != NULL; + for (item = context->input_devices; + item != NULL; item = item->next) { device = item->data; diff --git a/clutter/clutter-main.h b/clutter/clutter-main.h index d2eef79d0..81a4f8c12 100644 --- a/clutter/clutter-main.h +++ b/clutter/clutter-main.h @@ -89,6 +89,7 @@ ClutterInitError clutter_init_with_args (int *argc, char *translation_domain, GError **error); GOptionGroup * clutter_get_option_group (void); +GOptionGroup * clutter_get_option_group_without_init (void); /* Mainloop */ void clutter_main (void); diff --git a/clutter/clutter-private.h b/clutter/clutter-private.h index 9d902d6b6..2ccb65d4c 100644 --- a/clutter/clutter-private.h +++ b/clutter/clutter-private.h @@ -91,14 +91,16 @@ struct _ClutterMainContext system backend */ ClutterStageManager *stage_manager; /* stages */ GQueue *events_queue; /* the main event queue */ - + guint is_initialized : 1; + guint motion_events_per_actor : 1;/* set for enter/leave events */ + guint defer_display_setup : 1; + guint options_parsed : 1; + GTimer *timer; /* Used for debugging scheduler */ ClutterPickMode pick_mode; /* Indicates pick render mode */ - guint motion_events_per_actor : 1;/* set for enter/leave events */ - guint motion_frequency; /* Motion events per second */ gint num_reactives; /* Num of reactive actors */ diff --git a/clutter/x11/clutter-backend-x11.c b/clutter/x11/clutter-backend-x11.c index 3c8e345a7..c4123143f 100644 --- a/clutter/x11/clutter-backend-x11.c +++ b/clutter/x11/clutter-backend-x11.c @@ -57,7 +57,7 @@ struct _ClutterX11XInputDevice int num_events; #endif ClutterX11InputDeviceType type; /* FIXME: generic to ClutterInputDevice? */ -}; +}; #ifdef USE_XINPUT void _clutter_x11_register_xinput (); @@ -181,7 +181,7 @@ clutter_backend_x11_post_parse (ClutterBackend *backend, if (clutter_synchronise) XSynchronize (backend_x11->xdpy, True); - + XInternAtoms (backend_x11->xdpy, (char **) atom_names, n_atom_names, False, atoms); @@ -425,7 +425,9 @@ clutter_x11_get_default_display (void) void clutter_x11_set_display (Display *xdpy) { - if (backend_singleton && backend_singleton->xdpy) + ClutterMainContext *ctx = clutter_context_get_default (); + + if (ctx->is_initialized) { g_critical ("Display connection already exists. You can only call " "clutter_x11_set_display() once before clutter_init()\n"); @@ -450,11 +452,13 @@ clutter_x11_set_display (Display *xdpy) void clutter_x11_enable_xinput () { - if (backend_singleton != NULL) + ClutterMainContext *ctx = clutter_context_get_default (); + + if (ctx->is_initialized) { g_warning ("clutter_x11_enable_xinput should " "be called before clutter_init"); - return; + return; } _enable_xinput = TRUE; @@ -473,11 +477,13 @@ clutter_x11_enable_xinput () void clutter_x11_disable_event_retrieval (void) { - if (backend_singleton != NULL) + ClutterMainContext *ctx = clutter_context_get_default (); + + if (ctx->is_initialized) { g_warning ("clutter_x11_disable_event_retrieval should " "be called before clutter_init"); - return; + return; } _no_xevent_retrieval = TRUE; @@ -614,7 +620,7 @@ clutter_x11_remove_filter (ClutterX11FilterFunc func, #ifdef USE_XINPUT -void +void _clutter_x11_register_xinput () { XDeviceInfo *xdevices = NULL; @@ -629,7 +635,7 @@ _clutter_x11_register_xinput () gint num_events = 0; gint i = 0, j = 0; gboolean have_an_xpointer = FALSE; - + ClutterBackendX11 *x11b; ClutterX11XInputDevice *device = NULL; @@ -671,12 +677,12 @@ _clutter_x11_register_xinput () return; } - for (i = 0; i < num_devices; i++) + for (i = 0; i < num_devices; i++) { num_events = 0; info = xdevices + i; - CLUTTER_NOTE (BACKEND, "Considering %li with type %d", + CLUTTER_NOTE (BACKEND, "Considering %li with type %d", info->id, info->use); /* Only want 'raw' devices themselves not virtual ones */ @@ -720,7 +726,7 @@ _clutter_x11_register_xinput () break; } - CLUTTER_NOTE (BACKEND, "Registering XINPUT device with XID: %li", + CLUTTER_NOTE (BACKEND, "Registering XINPUT device with XID: %li", xdevice->device_id); /* We must go through all the classes supported by this device and @@ -737,33 +743,33 @@ _clutter_x11_register_xinput () #if 0 /* We do not do XInput keyboard events yet, since it is broken */ case KeyClass: - DeviceKeyPress (xdevice, - x11b->event_types [CLUTTER_X11_XINPUT_KEY_PRESS_EVENT], + DeviceKeyPress (xdevice, + x11b->event_types [CLUTTER_X11_XINPUT_KEY_PRESS_EVENT], device->xevent_list [num_events]); num_events++; - DeviceKeyRelease (xdevice, - x11b->event_types [CLUTTER_X11_XINPUT_KEY_RELEASE_EVENT], + DeviceKeyRelease (xdevice, + x11b->event_types [CLUTTER_X11_XINPUT_KEY_RELEASE_EVENT], device->xevent_list [num_events]); num_events++; break; #endif case ButtonClass: - DeviceButtonPress (xdevice, - x11b->event_types [CLUTTER_X11_XINPUT_BUTTON_PRESS_EVENT], + DeviceButtonPress (xdevice, + x11b->event_types [CLUTTER_X11_XINPUT_BUTTON_PRESS_EVENT], device->xevent_list [num_events]); num_events++; - DeviceButtonRelease (xdevice, - x11b->event_types [CLUTTER_X11_XINPUT_BUTTON_RELEASE_EVENT], + DeviceButtonRelease (xdevice, + x11b->event_types [CLUTTER_X11_XINPUT_BUTTON_RELEASE_EVENT], device->xevent_list [num_events]); num_events++; break; case ValuatorClass: - DeviceMotionNotify (xdevice, - x11b->event_types [CLUTTER_X11_XINPUT_MOTION_NOTIFY_EVENT], + DeviceMotionNotify (xdevice, + x11b->event_types [CLUTTER_X11_XINPUT_MOTION_NOTIFY_EVENT], device->xevent_list [num_events]); num_events++; break; @@ -813,15 +819,15 @@ _clutter_x11_select_events (Window xwin) return; } - for (list_it = context->input_devices; - list_it != NULL; + for (list_it = context->input_devices; + list_it != NULL; list_it = list_it->next) { device = (ClutterX11XInputDevice *)list_it->data; - XSelectExtensionEvent (backend_singleton->xdpy, + XSelectExtensionEvent (backend_singleton->xdpy, xwin, - device->xevent_list, + device->xevent_list, device->num_events); } } @@ -841,8 +847,8 @@ _clutter_x11_get_device_for_xid (XID id) return NULL; } - for (list_it = context->input_devices; - list_it != NULL; + for (list_it = context->input_devices; + list_it != NULL; list_it = list_it->next) { device = (ClutterX11XInputDevice *)list_it->data; @@ -894,7 +900,7 @@ clutter_x11_get_input_device_type (ClutterX11XInputDevice *device) /** * clutter_x11_has_xinput: - * + * * Gets whether Clutter has XInput support. * * Return value: %TRUE if Clutter was compiled with XInput support @@ -939,9 +945,9 @@ clutter_x11_has_composite_extension (void) if (XCompositeQueryExtension (dpy, &event, &error)) { int major = 0, minor = 0; - if (XCompositeQueryVersion (dpy, &major, &minor)) + if (XCompositeQueryVersion (dpy, &major, &minor)) { - if (major >= 0 && minor >= 3) + if (major >= 0 && minor >= 3) have_composite = TRUE; } }