示例#1
0
/* Switch to requested view */
static void _xfdashboard_application_switch_to_view(XfdashboardApplication *self, const gchar *inInternalViewName)
{
	GSList							*stages, *iter;

	g_return_if_fail(XFDASHBOARD_IS_APPLICATION(self));

	/* If no view name was specified then do nothing and return immediately */
	if(!inInternalViewName ||
		!inInternalViewName[0])
	{
		g_debug("No view to switch to specified");
		return;
	}

	/* Iterate through list of stages and set specified view at stage */
	g_debug("Trying to switch to view '%s'", inInternalViewName);

	stages=clutter_stage_manager_list_stages(clutter_stage_manager_get_default());
	for(iter=stages; iter; iter=g_slist_next(iter))
	{
		/* Tell stage to switch view */
		if(XFDASHBOARD_IS_STAGE(iter->data))
		{
			xfdashboard_stage_set_switch_to_view(XFDASHBOARD_STAGE(iter->data),
													inInternalViewName);
		}
	}
}
示例#2
0
ClutterActor *
_clutter_backend_create_stage (ClutterBackend  *backend,
                               ClutterStage    *wrapper,
                               GError         **error)
{
  ClutterBackendClass *klass;
  ClutterStageManager *stage_manager;
  ClutterActor        *stage = NULL;

  g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), FALSE);
  g_return_val_if_fail (CLUTTER_IS_STAGE (wrapper), FALSE);

  stage_manager = clutter_stage_manager_get_default ();

  klass = CLUTTER_BACKEND_GET_CLASS (backend);
  if (klass->create_stage)
    stage = klass->create_stage (backend, wrapper, error);

  if (!stage)
    return NULL;

  g_assert (CLUTTER_IS_STAGE_WINDOW (stage));
  _clutter_stage_set_window (wrapper, CLUTTER_STAGE_WINDOW (stage));
  _clutter_stage_manager_add_stage (stage_manager, wrapper);

  return stage;
}
static ClutterStageWindow *
clutter_backend_real_create_stage (ClutterBackend  *backend,
                                   ClutterStage    *wrapper,
                                   GError         **error)
{
  ClutterBackendClass *klass;

  if (!clutter_feature_available (CLUTTER_FEATURE_STAGE_MULTIPLE))
    {
      ClutterStageManager *manager = clutter_stage_manager_get_default ();

      if (clutter_stage_manager_get_default_stage (manager) != NULL)
        {
          g_set_error (error, CLUTTER_INIT_ERROR,
                       CLUTTER_INIT_ERROR_BACKEND,
                       _("The backend of type '%s' does not support "
                         "creating multiple stages"),
                       G_OBJECT_TYPE_NAME (backend));
          return NULL;
        }
    }

  klass = CLUTTER_BACKEND_GET_CLASS (backend);
  g_assert (klass->stage_window_type != G_TYPE_INVALID);

  return g_object_new (klass->stage_window_type,
                       "backend", backend,
                       "wrapper", wrapper,
                       NULL);
}
/**
 * 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
clutter_backend_win32_dispose (GObject *gobject)
{
  ClutterBackend *backend = CLUTTER_BACKEND (gobject);
  ClutterBackendWin32 *backend_win32 = CLUTTER_BACKEND_WIN32 (gobject);
  ClutterStageManager *stage_manager;

  CLUTTER_NOTE (BACKEND, "Disposing the of stages");
  stage_manager = clutter_stage_manager_get_default ();

  g_object_unref (stage_manager);

  CLUTTER_NOTE (BACKEND, "Removing the event source");
  _clutter_backend_win32_events_uninit (CLUTTER_BACKEND (backend_win32));

  /* Unrealize all shaders, since the GL context is going away */
  _clutter_shader_release_all ();

  G_OBJECT_CLASS (clutter_backend_win32_parent_class)->dispose (gobject);

  if (backend->cogl_context)
    {
      cogl_object_unref (backend->cogl_context);
      backend->cogl_context = NULL;
    }
}
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);
}
示例#11
0
/*
 * 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;
}
示例#12
0
/**
 * mpl_panel_clutter_init_with_gtk:
 * @argc: (inout): a pointer to the number of command line arguments
 * @argv: (array length=argc) (inout) (allow-none): a pointer to the array
 *   of command line arguments
 *
 * Initialializes the libdawati-panel library when used in a Clutter-based
 * panel that also use Gtk (panels that only use Clutter should use
 * mpl_panel_clutter_init_lib() instead).
 *
 * This function calls gtk_init() and clutter_init().
 */
void
mpl_panel_clutter_init_with_gtk (gint *argc, gchar ***argv)
{
  ClutterStageManager *manager;

  gtk_init (argc, argv);
  clutter_x11_set_display (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
  clutter_x11_disable_event_retrieval ();

  if (CLUTTER_INIT_SUCCESS != clutter_init (argc, argv))
    {
      g_error ("Unable to initialize Clutter.\n");
    }

  manager = clutter_stage_manager_get_default ();
  g_signal_connect_after (manager, "stage-added",
                          G_CALLBACK (_stage_added),
                          NULL);

  mpl_panel_clutter_load_base_style ();
}
示例#13
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);
    }
}
示例#14
0
/* Quit application depending on daemon mode and force parameter */
static void _xfdashboard_application_quit(XfdashboardApplication *self, gboolean inForceQuit)
{
	XfdashboardApplicationPrivate	*priv;
	gboolean						shouldQuit;
	GSList							*stages, *entry;

	g_return_if_fail(XFDASHBOARD_IS_APPLICATION(self));

	priv=self->priv;
	shouldQuit=FALSE;

	/* Check if we should really quit this instance */
	if(inForceQuit==TRUE || priv->isDaemon==FALSE) shouldQuit=TRUE;

	/* Do nothing if application is already quitting. This can happen if
	 * application is running in daemon mode (primary instance) and another
	 * instance was called with "quit" or "restart" parameter which would
	 * cause this function to be called twice.
	 */
	if(priv->isQuitting) return;

	/* If application is not in daemon mode or if forced is set to TRUE
	 * destroy all stage windows ...
	 */
	if(shouldQuit==TRUE)
	{
		/* Set flag that application is going to quit */
		priv->isQuitting=TRUE;

		/* If application is told to quit, set the restart style to something
		 * where it won't restart itself.
		 */
		if(priv->sessionManagementClient &&
			XFCE_IS_SM_CLIENT(priv->sessionManagementClient))
		{
			xfce_sm_client_set_restart_style(priv->sessionManagementClient, XFCE_SM_CLIENT_RESTART_NORMAL);
		}

		/* Destroy stages */
		stages=clutter_stage_manager_list_stages(clutter_stage_manager_get_default());
		for(entry=stages; entry!=NULL; entry=g_slist_next(entry)) clutter_actor_destroy(CLUTTER_ACTOR(entry->data));
		g_slist_free(stages);

		/* Emit "quit" signal */
		g_signal_emit(self, XfdashboardApplicationSignals[SIGNAL_QUIT], 0);

		/* Really quit application here and now */
		if(priv->inited) clutter_main_quit();
	}
		/* ... otherwise emit "suspend" signal */
		else
		{
			/* Only send signal if not suspended already */
			if(!priv->isSuspended)
			{
				/* Send signal */
				g_signal_emit(self, XfdashboardApplicationSignals[SIGNAL_SUSPEND], 0);

				/* Set flag for suspension */
				priv->isSuspended=TRUE;
				g_object_notify_by_pspec(G_OBJECT(self), XfdashboardApplicationProperties[PROP_SUSPENDED]);
			}
		}
}
示例#15
0
/**
 * 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);
}
示例#16
0
static gboolean
clutter_clock_dispatch (GSource     *source,
                        GSourceFunc  callback,
                        gpointer     user_data)
{
  ClutterClockSource *clock_source = (ClutterClockSource *) source;
  ClutterMasterClock *master_clock = clock_source->master_clock;
  ClutterStageManager *stage_manager = clutter_stage_manager_get_default ();
  gboolean stages_updated = FALSE;
  GSList *stages, *l;

  CLUTTER_STATIC_TIMER (master_dispatch_timer,
                        "Mainloop",
                        "Master Clock",
                        "Master clock dispatch",
                        0);
  CLUTTER_STATIC_TIMER (master_event_process,
                        "Master Clock",
                        "Event Processing",
                        "The time spent processing events on all stages",
                        0);

  CLUTTER_TIMER_START (_clutter_uprof_context, master_dispatch_timer);

  CLUTTER_NOTE (SCHEDULER, "Master clock [tick]");

  clutter_threads_enter ();

  /* Get the time to use for this frame */
#if GLIB_CHECK_VERSION (2, 27, 3)
  master_clock->cur_tick = g_source_get_time (source);
#else
  {
    GTimeVal source_time;
    g_source_get_current_time (source, &source_time);
    master_clock->cur_tick = source_time.tv_sec * 1000000L
                           + source_time.tv_usec;
  }
#endif

  /* We need to protect ourselves against stages being destroyed during
   * event handling
   */
  stages = clutter_stage_manager_list_stages (stage_manager);
  g_slist_foreach (stages, (GFunc) g_object_ref, NULL);

  CLUTTER_TIMER_START (_clutter_uprof_context, master_event_process);

  master_clock->idle = FALSE;

  /* Process queued events */
  for (l = stages; l != NULL; l = l->next)
    {
      /* NB: If a stage is busy waiting for a swap-buffers completion then
       * we don't process its events so we can maximize the benefits of
       * motion compression, and avoid multiple picks per frame.
       */
      if (_clutter_stage_get_pending_swaps (l->data) == 0)
        _clutter_stage_process_queued_events (l->data);
    }

  CLUTTER_TIMER_STOP (_clutter_uprof_context, master_event_process);

  _clutter_master_clock_advance (master_clock);

  _clutter_run_repaint_functions ();

  /* Update any stage that needs redraw/relayout after the clock
   * is advanced.
   */
  for (l = stages; l != NULL; l = l->next)
    {
      /* 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_stage_get_pending_swaps (l->data) == 0)
        stages_updated |= _clutter_stage_do_update (l->data);
    }

  /* The master clock goes idle if no stages were updated and falls back
   * to polling for timeline progressions... */
  if (!stages_updated)
    master_clock->idle = TRUE;

  g_slist_foreach (stages, (GFunc) g_object_unref, NULL);
  g_slist_free (stages);

  master_clock->prev_tick = master_clock->cur_tick;

  clutter_threads_leave ();

  CLUTTER_TIMER_STOP (_clutter_uprof_context, master_dispatch_timer);

  return TRUE;
}