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