1 #ifndef __GSK_HOOK_H_
2 #define __GSK_HOOK_H_
3 
4 #include <glib-object.h>
5 
6 /* GskHook: a blockable, optionally shutdown-able, hookable thing
7  *          inside an object.
8  *
9  *  well, there's a bunch of other constraints;
10  *  in many ways this is just a bunch of private details of gskio,
11  *  but i thought it might be generally useful by encapsulating
12  *  it in this way.
13  *
14  *
15  *  the encapsulation here is pretty minimal:  GskHook must be a
16  *  member of a GObject-derived class.  it must have a member to
17  *  trap/untrap reading/writing (unless it never blocks)
18  *  and it may have an optional shutdown method.
19  *
20  *  specifically, your Class should probably contain functions like
21  *
22  *      void (*set_poll) (Object    *object,
23  *                        gboolean   do_polling);
24  *      void (*shutdown) (Object    *object);
25  * or, if SHUTDOWN_HAS_ERROR,
26  *      gboolean (*shutdown) (Object    *object,
27  *                            GError   **error);
28  *
29  */
30 
31 G_BEGIN_DECLS
32 
33 typedef struct _GskHook GskHook;
34 
35 typedef gboolean (*GskHookFunc) (GObject     *object,
36 				 gpointer     data);
37 
38 /* just for reference: these are the prototypes of the two members
39  * described above that may/should appear in your Class structure. */
40 typedef void     (*GskHookSetPollFunc) (GObject      *object,
41 					gboolean      do_polling);
42 typedef void     (*GskHookShutdownFunc)(GObject      *object);
43 typedef gboolean (*GskHookShutdownErrorFunc)(GObject      *object,
44 					     GError      **error);
45 
46 
47 /* note: fits in 16 bits */
48 typedef enum
49 {
50   GSK_HOOK_IS_AVAILABLE            	= (1 << 0),
51   GSK_HOOK_NEVER_AUTO_SHUTS_DOWN   	= (1 << 1),
52   GSK_HOOK_CAN_HAVE_SHUTDOWN_ERROR 	= (1 << 2),
53   GSK_HOOK_private_IDLE_NOTIFY     	= (1 << 3), /*< private >*/
54   GSK_HOOK_private_JUST_NEVER_BLOCKS    = (1 << 4), /*< private >*/
55   GSK_HOOK_private_NEVER_BLOCKS		= (GSK_HOOK_private_IDLE_NOTIFY | GSK_HOOK_private_JUST_NEVER_BLOCKS), /*< private >*/
56   GSK_HOOK_private_CAN_DEFER_SHUTDOWN   = (1 << 5), /*< private >*/
57   GSK_HOOK_private_SHUTTING_DOWN        = (1 << 6), /*< private >*/
58   _GSK_HOOK_FLAGS_RESERVED	   	= (0xff << 8), /*< private >*/
59 } GskHookFlags;
60 
61 #define GSK_HOOK_TEST_FLAG(hook, flag_shortname)	\
62 	(((hook)->flags & GSK_HOOK_ ## flag_shortname) == GSK_HOOK_ ## flag_shortname)
63 #define GSK_HOOK_MARK_FLAG(hook, flag_shortname)		\
64 	((hook)->flags |= (GSK_HOOK_ ## flag_shortname))
65 #define GSK_HOOK_CLEAR_FLAG(hook, flag_shortname)	\
66 	((hook)->flags &= ~(GSK_HOOK_ ## flag_shortname))
67 #define GSK_HOOK_TEST_IDLE_NOTIFY(hook)  GSK_HOOK_TEST_FLAG(hook, private_IDLE_NOTIFY)
68 #define GSK_HOOK_TEST_NEVER_BLOCKS(hook) GSK_HOOK_TEST_FLAG(hook, private_NEVER_BLOCKS)
69 #define GSK_HOOK_TEST_IS_AVAILABLE(hook) GSK_HOOK_TEST_FLAG(hook, IS_AVAILABLE)
70 #define GSK_HOOK_TEST_SHUTTING_DOWN(hook) GSK_HOOK_TEST_FLAG(hook, private_SHUTTING_DOWN)
71 
72 /*< protected >*/
73 #define GSK_HOOK_TEST_USER_FLAG(hook, bit)		\
74   (((hook)->user_flags & (bit)) == (bit))
75 #define GSK_HOOK_MARK_USER_FLAG(hook, bit)		\
76   ((hook)->user_flags |= (bit))
77 #define GSK_HOOK_CLEAR_USER_FLAG(hook, bit)		\
78   ((hook)->user_flags &= ~(bit))
79 
80 #define GSK_HOOK_GET_OBJECT(hook)	(G_OBJECT ((char *) (hook) - (hook)->inset))
81 
82 struct _GskHook
83 {
84   /*< private >*/
85   guint16 flags;
86   guint16 user_flags;		/* for use by containing class */
87   guint16 block_count;
88   guint16 inset;
89   guint16 class_set_poll_offset;
90   guint16 class_shutdown_offset;
91 
92   GskHookFunc func;
93   GskHookFunc shutdown_func;
94   gpointer data;
95   GDestroyNotify destroy;
96 };
97 
98 
99 /*< public >*/
100 void     gsk_hook_trap            (GskHook        *hook,
101                                    GskHookFunc     func,
102 				   GskHookFunc     shutdown,
103                                    gpointer        data,
104                                    GDestroyNotify  destroy);
105 void     gsk_hook_untrap          (GskHook        *hook);
106 #define gsk_hook_is_trapped(hook) (((hook)->func) != NULL)
107 void     gsk_hook_block           (GskHook        *hook);
108 void     gsk_hook_unblock         (GskHook        *hook);
109 gboolean gsk_hook_shutdown        (GskHook        *hook,
110 				   GError        **error);
111 
112 /*< protected: for use by implementations of objects which have hooks >*/
113 void     gsk_hook_init            (GskHook        *hook,
114                                    GskHookFlags    flags,
115                                    guint           inset,
116                                    guint           class_set_poll_offset,
117                                    guint           class_shutdown_offset);
118 void     gsk_hook_class_init      (GObjectClass   *object_class,
119 				   const char     *name,
120 				   guint           hook_offset);
121 void     gsk_hook_notify          (GskHook        *hook);
122 void     gsk_hook_notify_shutdown (GskHook        *hook);
123 void     gsk_hook_destruct        (GskHook        *hook);
124 
125 void     gsk_hook_set_idle_notify   (GskHook        *hook,
126 				     gboolean        should_idle_notify);
127 void     gsk_hook_mark_idle_notify  (GskHook        *hook);
128 void     gsk_hook_clear_idle_notify (GskHook        *hook);
129 void     gsk_hook_mark_never_blocks  (GskHook        *hook);
130 void     gsk_hook_mark_can_defer_shutdown (GskHook        *hook);
131 gboolean gsk_hook_get_last_poll_state(GskHook       *hook);
132 
133 /* macros for more conveniently initializing hooks from *_init */
134 #define GSK_HOOK_INIT(object, struct, member, flags, set_poll, shutdown)   \
135         gsk_hook_init (&(object)->member,                                  \
136                        flags, G_STRUCT_OFFSET (struct, member),            \
137                        G_STRUCT_OFFSET (struct ## Class, set_poll),        \
138                        G_STRUCT_OFFSET (struct ## Class, shutdown))
139 #define GSK_HOOK_INIT_NO_SHUTDOWN(object, struct, member, flags, set_poll) \
140         gsk_hook_init (&(object)->member,                                  \
141                        flags, G_STRUCT_OFFSET (struct, member),            \
142                        G_STRUCT_OFFSET (struct ## Class, set_poll), 0)
143 #define GSK_HOOK_CLASS_INIT(object_class, hook_name, Type, member)	   \
144   	gsk_hook_class_init (object_class, hook_name,			   \
145 			     G_STRUCT_OFFSET (Type, member))
146 
147 /* private: initialize the hook system (called by gsk_init()) >*/
148 void  _gsk_hook_init ();
149 
150 #ifndef GSK_DISABLE_DEPRECATED
151 #define GSK_HOOK_SET_FLAG GSK_HOOK_MARK_FLAG
152 #endif
153 
154 G_END_DECLS
155 
156 #endif
157