/**
 * 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;
}
Exemple #8
0
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);
}