diff include/mb_observer.h @ 224:29e1b2bffe4c

X backend only sent EVT_MOUSE_MOVE_RAW to MadButterfly. - backend does not interpret mouse events (over/out/move), now. - redraw manager, now, interpret mouse events to make it backend independent. - The task (interpret mouse events) should be moved to somewhere in futhure. - backend only sent MotionNotify as EVT_MOUSE_MOVE_RAW. - EVT_MOUSE_MOVE_RAW is interpreted by backend independent code.
author Thinker K.F. Li <thinker@branda.to>
date Mon, 15 Dec 2008 10:13:03 +0800
parents 748896358da2
children 586e50f82c1f
line wrap: on
line diff
--- a/include/mb_observer.h	Sun Dec 14 12:53:45 2008 +0800
+++ b/include/mb_observer.h	Mon Dec 15 10:13:03 2008 +0800
@@ -7,14 +7,25 @@
 typedef struct _observer observer_t;
 typedef struct _subject subject_t;
 typedef struct _mouse_event mouse_event_t;
+typedef struct _monitor_event monitor_event_t;
 typedef struct _ob_factory ob_factory_t;
 typedef void (*evt_handler)(event_t *event, void *arg);
 
 struct _event {
-    int type;			/*!< event type (a.k.a. EVT_*  */
+    int type;			/*!< event type (a.k.a. EVT_*)  */
     subject_t *tgt, *cur_tgt;
+    int flags;
 };
 
+/*! \brief Observer mark event with EVTF_STOP_PROPAGATE flag
+ *	   to stop propagation.
+ */
+#define EVTF_STOP_PROPAGATE 0x1
+/*! \brief Observer mark event with EVTF_STOP_NOTIFY flag to stop
+ *	   stop notification the event immediately.
+ */
+#define EVTF_STOP_NOTIFY 0x2
+
 /*! \brief Observer of observer pattern.
  *
  * A target for receiving events.
@@ -31,15 +42,21 @@
  * Observer is a pattern to decouple caller and callee,
  * especial for multiple callee.
  * \see http://en.wikipedia.org/wiki/Observer_pattern
+ *
+ * This implementation add a monitor facility to monitor adding/removing
+ * observers from subjects.  Monitor is another subject that monitor events
+ * will be sent to if it is existed.
  */
 struct _subject {
     int obj_type;		/*!< \brief type of object (a.k.a. OBJT_*). */
     void *obj;			/*!< \brief the object this subject for. */
     int flags;
+    subject_t *monitor_sub;	/*!< \brief Monitor adding/removing
+				 *          obervers on this subject. */
     ob_factory_t *factory;
     STAILQ(observer_t) observers;
 };
-/*! \brief Flag that make a subject to propagate events to parents. */
+/*! \brief Flag that make a subject to stop propagate events to parents. */
 #define SUBF_STOP_PROPAGATE 0x1
 #define SUBF_BUSY 0x2		/*!< \brief in subject_notify() */
 #define SUBF_FREE 0x4		/*!< \brief in postponding subject_free() */
@@ -57,6 +74,12 @@
 #define MOUSE_BUT2 0x2
 #define MOUSE_BUT3 0x4
 
+struct _monitor_event {
+    event_t event;
+    subject_t *subject;	  /*!< \brief Subject been monitored. */
+    observer_t *observer; /*!< \brief Observer been added or removed. */
+};
+
 /*! \brief Observer factory.
  *
  * It provides functions for allocation of subject and observer objects,
@@ -75,18 +98,39 @@
 enum {EVT_ANY,EVT_MOUSE_OVER, EVT_MOUSE_OUT, EVT_MOUSE_MOVE,
       EVT_MOUSE_BUT_PRESS, EVT_MOUSE_BUT_RELEASE,
       EVT_KB_PRESS, EVT_KB_RELEASE, EVT_PROGM_COMPLETE,
-      EVT_RDMAN_REDRAW };
+      EVT_RDMAN_REDRAW,
+      EVT_MONITOR_ADD, EVT_MONITOR_REMOVE, EVT_MONITOR_FREE,
+      EVT_MOUSE_MOVE_RAW
+};
 
 extern subject_t *subject_new(ob_factory_t *factory,
 			      void *obj, int obj_type);
 extern void subject_free(subject_t *subject);
 extern void subject_notify(subject_t *subject, event_t *evt);
-extern observer_t *subject_add_observer(subject_t *subject,
-					evt_handler hdr, void *arg);
 extern observer_t *subject_add_event_observer(subject_t *subject, int type,
 					      evt_handler hdr, void *arg);
+/*! \brief Add an observer for any type of events. */
+#define subject_add_observer(s, h, a)			\
+    subject_add_event_observer(s, EVT_ANY, h, a)
+extern observer_t *subject_add_event_observer_head(subject_t *subject,
+						   int type,
+						   evt_handler hdr,
+						   void *arg);
+/*! \brief Add an observer for any type of events at head. */
+#define subject_add_observer_head(s, h, a)		\
+    subject_add_event_observer_head(s, EVT_ANY, h, a)
 extern void subject_remove_observer(subject_t *subject,
 				    observer_t *observer);
+#define subject_get_object(s) ((s)->obj)
 
+/*! \brief Set monitor for the subject.
+ *
+ * Monitor of a subject is another subject that would be notified when
+ * add/remove a observer to/from the subject.  It can be used to efficiently
+ * implement translator to translate events.
+ */
+#define subject_set_monitor(subject, monitor)	\
+    do { (subject)->monitor_sub = monitor; } while(0)
+#define subject_monitor(subject) ((subject)->monitor_sub)
 
 #endif /* __OBSERVER_H_ */