663
666
return nexus_type;
669
/***************************************************************************
670
* Later functions: like idles but integrated with the Clutter repaint loop
671
***************************************************************************/
673
static guint last_later_id = 0;
681
GDestroyNotify notify;
686
static GSList *laters = NULL;
687
/* This is a dummy timeline used to get the Clutter master clock running */
688
static ClutterTimeline *later_timeline;
689
static guint later_repaint_func = 0;
691
static void ensure_later_repaint_func (void);
694
destroy_later (MetaLater *later)
697
g_source_remove (later->source);
699
later->notify (later->data);
700
g_slice_free (MetaLater, later);
703
/* Used to sort the list of laters with the highest priority
707
compare_laters (gconstpointer a,
710
return ((const MetaLater *)a)->when - ((const MetaLater *)b)->when;
714
run_repaint_laters (gpointer data)
716
GSList *old_laters = laters;
718
gboolean keep_timeline_running = FALSE;
721
for (l = old_laters; l; l = l->next)
723
MetaLater *later = l->data;
724
if (later->source == 0 ||
725
(later->when <= META_LATER_BEFORE_REDRAW && !later->run_once))
727
if (later->func (later->data))
729
if (later->source == 0)
730
keep_timeline_running = TRUE;
731
laters = g_slist_insert_sorted (laters, later, compare_laters);
734
destroy_later (later);
737
laters = g_slist_insert_sorted (laters, later, compare_laters);
740
if (!keep_timeline_running)
741
clutter_timeline_stop (later_timeline);
743
g_slist_free (old_laters);
745
/* Just keep the repaint func around - it's cheap if the list is empty */
750
ensure_later_repaint_func (void)
753
later_timeline = clutter_timeline_new (G_MAXUINT);
755
if (later_repaint_func == 0)
756
later_repaint_func = clutter_threads_add_repaint_func (run_repaint_laters,
759
/* Make sure the repaint function gets run */
760
clutter_timeline_start (later_timeline);
764
call_idle_later (gpointer data)
766
MetaLater *later = data;
768
if (!later->func (later->data))
770
laters = g_slist_remove (laters, later);
772
destroy_later (later);
777
later->run_once = TRUE;
784
* @when: enumeration value determining the phase at which to run the callback
785
* @func: callback to run later
786
* @data: data to pass to the callback
787
* @notify: function to call to destroy @data when it is no longer in use, or %NULL
789
* Sets up a callback to be called at some later time. @when determines the
790
* particular later occasion at which it is called. This is much like g_idle_add(),
791
* except that the functions interact properly with clutter event handling.
792
* If a "later" function is added from a clutter event handler, and is supposed
793
* to be run before the stage is redrawn, it will be run before that redraw
794
* of the stage, not the next one.
796
* Return value: an integer ID (guaranteed to be non-zero) that can be used
797
* to cancel the callback and prevent it from being run.
800
meta_later_add (MetaLaterType when,
803
GDestroyNotify notify)
805
MetaLater *later = g_slice_new0 (MetaLater);
807
later->id = ++last_later_id;
811
later->notify = notify;
813
laters = g_slist_insert_sorted (laters, later, compare_laters);
817
case META_LATER_RESIZE:
818
/* We add this one two ways - as a high-priority idle and as a
819
* repaint func. If we are in a clutter event callback, the repaint
820
* handler will get hit first, and we'll take care of this function
821
* there so it gets called before the stage is redrawn, even if
822
* we haven't gotten back to the main loop. Otherwise, the idle
823
* handler will get hit first and we want to call this function
824
* there so it will happen before GTK+ repaints.
826
later->source = g_idle_add_full (META_PRIORITY_RESIZE, call_idle_later, later, NULL);
827
ensure_later_repaint_func ();
829
case META_LATER_BEFORE_REDRAW:
830
ensure_later_repaint_func ();
832
case META_LATER_IDLE:
833
later->source = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, call_idle_later, later, NULL);
842
* @later_id: the integer ID returned from meta_later_add()
844
* Removes a callback added with meta_later_add()
847
meta_later_remove (guint later_id)
851
for (l = laters; l; l = l->next)
853
MetaLater *later = l->data;
854
if (later->id == later_id)
856
laters = g_slist_remove_link (laters, l);
857
/* If this was a "repaint func" later, we just let the
858
* repaint func run and get removed
860
destroy_later (later);