/** * clutter_win32_get_stage_from_window: * @hwnd: a window handle * * Gets the stage for a particular window. * * Return value: The stage or NULL if a stage does not exist for the * window. * * Since: 0.8 */ ClutterStage * clutter_win32_get_stage_from_window (HWND hwnd) { /* Check whether the window handle is an instance of the stage window class */ if ((ATOM) GetClassLongPtrW (hwnd, GCW_ATOM) == clutter_stage_win32_get_window_class ()) /* If it is there should be a pointer to the stage in the window extra data */ return CLUTTER_STAGE_WIN32 (GetWindowLongPtrW (hwnd, 0))->wrapper; else { /* Otherwise it might be a foreign window so we should check the stage list */ ClutterStageManager *stage_manager; const GSList *stages, *l; stage_manager = clutter_stage_manager_get_default (); stages = clutter_stage_manager_peek_stages (stage_manager); for (l = stages; l != NULL; l = l->next) { ClutterStage *stage = l->data; ClutterStageWindow *impl; impl = _clutter_stage_get_window (stage); g_assert (CLUTTER_IS_STAGE_WIN32 (impl)); if (CLUTTER_STAGE_WIN32 (impl)->hwnd == hwnd) return stage; } } return NULL; }
static gboolean clutter_clock_prepare (GSource *source, gint *timeout) { ClutterClockSource *clock_source = (ClutterClockSource *) source; ClutterMasterClockDefault *master_clock = clock_source->master_clock; int delay; _clutter_threads_acquire_lock (); if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_CONTINUOUS_REDRAW)) { ClutterStageManager *stage_manager = clutter_stage_manager_get_default (); const GSList *stages, *l; stages = clutter_stage_manager_peek_stages (stage_manager); /* Queue a full redraw on all of the stages */ for (l = stages; l != NULL; l = l->next) clutter_actor_queue_redraw (l->data); } delay = master_clock_next_frame_delay (master_clock); _clutter_threads_release_lock (); *timeout = delay; return delay == 0; }
static GSList * master_clock_list_ready_stages (ClutterMasterClockDefault *master_clock) { ClutterStageManager *stage_manager = clutter_stage_manager_get_default (); const GSList *stages, *l; GSList *result; stages = clutter_stage_manager_peek_stages (stage_manager); result = NULL; for (l = stages; l != NULL; l = l->next) { gint64 update_time = _clutter_stage_get_update_time (l->data); /* We carefully avoid to update stages that aren't mapped, because * they have nothing to render and this could cause a deadlock with * some of the SwapBuffers implementations (in particular * GLX_INTEL_swap_event is not emitted if nothing was rendered). * * Also, if a stage has a swap-buffers pending we don't want to draw * to it in case the driver may block the CPU while it waits for the * next backbuffer to become available. * * TODO: We should be able to identify if we are running triple or N * buffered and in these cases we can still draw if there is 1 swap * pending so we can hopefully always be ready to swap for the next * vblank and really match the vsync frequency. */ if (clutter_actor_is_mapped (l->data) && update_time != -1 && update_time <= master_clock->cur_tick) result = g_slist_prepend (result, g_object_ref (l->data)); } return g_slist_reverse (result); }
static gint master_clock_get_swap_wait_time (ClutterMasterClockDefault *master_clock) { ClutterStageManager *stage_manager = clutter_stage_manager_get_default (); const GSList *stages, *l; gint64 min_update_time = -1; stages = clutter_stage_manager_peek_stages (stage_manager); for (l = stages; l != NULL; l = l->next) { gint64 update_time = _clutter_stage_get_update_time (l->data); if (min_update_time == -1 || (update_time != -1 && update_time < min_update_time)) min_update_time = update_time; } if (min_update_time == -1) { return -1; } else { gint64 now = g_source_get_time (master_clock->source); if (min_update_time < now) { return 0; } else { gint64 delay_us = min_update_time - now; return (delay_us + 999) / 1000; } } }
/* * master_clock_is_running: * @master_clock: a #ClutterMasterClock * * Checks if we should currently be advancing timelines or redrawing * stages. * * Return value: %TRUE if the #ClutterMasterClock has at least * one running timeline */ static gboolean master_clock_is_running (ClutterMasterClockDefault *master_clock) { ClutterStageManager *stage_manager = clutter_stage_manager_get_default (); const GSList *stages, *l; stages = clutter_stage_manager_peek_stages (stage_manager); if (master_clock->paused) return FALSE; if (master_clock->timelines) return TRUE; for (l = stages; l; l = l->next) { if (clutter_actor_is_mapped (l->data) && (_clutter_stage_has_queued_events (l->data) || _clutter_stage_needs_update (l->data))) return TRUE; } if (master_clock->ensure_next_iteration) { master_clock->ensure_next_iteration = FALSE; return TRUE; } return FALSE; }
static void master_clock_schedule_stage_updates (ClutterMasterClockDefault *master_clock) { ClutterStageManager *stage_manager = clutter_stage_manager_get_default (); const GSList *stages, *l; stages = clutter_stage_manager_peek_stages (stage_manager); for (l = stages; l != NULL; l = l->next) _clutter_stage_schedule_update (l->data); }
/* * master_clock_is_running: * @master_clock: a #ClutterMasterClock * * Checks if we should currently be advancing timelines or redrawing * stages. * * Return value: %TRUE if the #ClutterMasterClock has at least * one running timeline */ static gboolean master_clock_is_running (ClutterMasterClock *master_clock) { ClutterStageManager *stage_manager = clutter_stage_manager_get_default (); const GSList *stages, *l; gboolean stage_free = FALSE; stages = clutter_stage_manager_peek_stages (stage_manager); /* If all of the stages are busy waiting for a swap-buffers to complete * then we stop the master clock... */ for (l = stages; l != NULL; l = l->next) { if (_clutter_stage_get_pending_swaps (l->data) == 0) { stage_free = TRUE; break; } } if (!stage_free) return FALSE; if (master_clock->timelines) return TRUE; for (l = stages; l; l = l->next) { if (_clutter_stage_has_queued_events (l->data) || _clutter_stage_needs_update (l->data)) return TRUE; } if (master_clock->ensure_next_iteration) { master_clock->ensure_next_iteration = FALSE; return TRUE; } return FALSE; }
static void mex_lirc_do_event (ClutterEvent *event) { const GSList *s; ClutterStageManager *stage_manager = clutter_stage_manager_get_default (); const GSList *stages = clutter_stage_manager_peek_stages (stage_manager); /* FIXME: We should probably check if the stage has focus via X */ for (s = stages; s; s = s->next) { ClutterStage *stage = s->data; ClutterActor *actor = clutter_stage_get_key_focus (stage); if (!actor) continue; event->any.stage = stage; event->any.source = actor; clutter_do_event (event); } }
/** * xfdashboard_notify: * @inSender: The sending #ClutterActor or %NULL * @inIconName: The icon name to display in notification or %NULL * @inFormat: A standard printf() format string for notification text * @...: The parameters to insert into the format string * * Shows a notification with the formatted text as specified in @inFormat * and the parameters at the monitor where the sending actor @inSender * is placed on. * * If @inSender is NULL the primary monitor is used. * * If @inIconName is NULL no icon will be shown in notification. */ void xfdashboard_notify(ClutterActor *inSender, const gchar *inIconName, const gchar *inFormat, ...) { XfdashboardStage *stage; ClutterStageManager *stageManager; va_list args; gchar *text; g_return_if_fail(inSender==NULL || CLUTTER_IS_ACTOR(inSender)); stage=NULL; /* Build text to display */ va_start(args, inFormat); text=g_strdup_vprintf(inFormat, args); va_end(args); /* Get stage of sending actor if available */ if(inSender) stage=XFDASHBOARD_STAGE(clutter_actor_get_stage(inSender)); /* No sending actor specified or no stage found so get default stage */ if(!stage) { const GSList *stages; const GSList *stagesIter; ClutterActorIter interfaceIter; ClutterActor *child; XfdashboardWindowTrackerMonitor *stageMonitor; /* Get stage manager to iterate through stages to find the one * for primary monitor or at least the first stage. */ stageManager=clutter_stage_manager_get_default(); /* Find stage for primary monitor and if we cannot find it * use first stage. */ if(stageManager && CLUTTER_IS_STAGE_MANAGER(stageManager)) { /* Get list of all stages */ stages=clutter_stage_manager_peek_stages(stageManager); /* Iterate through list of all stage and lookup the one for * primary monitor. */ for(stagesIter=stages; stagesIter && !stage; stagesIter=stagesIter->next) { /* Skip this stage if it is not a XfdashboardStage */ if(!XFDASHBOARD_IS_STAGE(stagesIter->data)) continue; /* Iterate through stage's children and lookup stage interfaces */ clutter_actor_iter_init(&interfaceIter, CLUTTER_ACTOR(stagesIter->data)); while(clutter_actor_iter_next(&interfaceIter, &child)) { if(XFDASHBOARD_IS_STAGE_INTERFACE(child)) { stageMonitor=xfdashboard_stage_interface_get_monitor(XFDASHBOARD_STAGE_INTERFACE(child)); if(xfdashboard_window_tracker_monitor_is_primary(stageMonitor)) { stage=XFDASHBOARD_STAGE(clutter_actor_get_stage(child)); } } } } /* If we did not get stage for primary monitor use first stage */ if(!stage && stages) { stage=XFDASHBOARD_STAGE(stages->data); } } /* If we still do not have found a stage to show notification * stop further processing and show notification text as a critical * warning in addition to the critical warning that we could not * find any stage. */ if(!stage) { g_critical(_("Could find any stage to show notification: %s"), text); } } /* Show notification on stage (if any found) */ if(stage) xfdashboard_stage_show_notification(stage, inIconName, text); /* Release allocated resources */ g_free(text); }