00001 /*! \page event_dispatching Event Dispatching Mechanism in MadButterfly 00002 * 00003 * \section evt_intro Introduction 00004 * 00005 * Event dispatching is an important job for the GUI system. Usually, 00006 * we need to handle the following events in the GUI 00007 * 00008 * - Mouse/pointer events 00009 * - Key event 00010 * - timer event 00011 * - IO event 00012 * - Repaint event 00013 * 00014 * In the rest of this article, I will discuss the event mechanism of 00015 * the MadButterfly and provide a design of event API. 00016 * 00017 * First thing go first. We will start from the most important event - 00018 * mouse evnets. 00019 * 00020 * \section evt_mouse Mouse/point events 00021 * 00022 * MadButterfly use observer design pattern to implement the event 00023 * dispatching. In this pattern, observer and subject are used to 00024 * handle events. The subject is a specific type of events. For 00025 * example, mouse events or keyboard events. Each subject can have zero 00026 * or more observers. When the system send events related to the subject, 00027 * it will call the subject_notify function of the subject, which will 00028 * notify every registered observers. 00029 * 00030 * In this way, we can decouple the components which send the events and 00031 * the components which need the events. For example, if we implement the 00032 * X and GTK backend, both of them will call subject_notify when it 00033 * receive the mouse events from the X or GTK. The observers don't 00034 * care whether the notification coming from X or GTK. The X and GTK 00035 * backend are responsible to translate the X or GTK mouse events into 00036 * the mouse subject. 00037 * 00038 * Therefore, we can use the subject as the astraction layer between 00039 * MadButterfly clients and the backend. 00040 * 00041 * To be more specific, in the current X backend. When it receive a 00042 * MotionNotify mouse event from the X server, it will send an mouse 00043 * event to the mouse event subject ob type OBJT_GEO. 00044 * \code 00045 * mouse_event.event.type = etype; 00046 * mouse_event.x = x; 00047 * mouse_event.y = y; 00048 * mouse_event.but_state = state; 00049 * mouse_event.button = button; 00050 * subject = sh_get_mouse_event_subject(shape); 00051 * factory = rdman_get_ob_factory(rdman); 00052 * subject_notify(factory, subject, (event_t *)&mouse_event); 00053 * \endcode 00054 * 00055 * The shape above is determined by the mouse position and the etype 00056 * is determined the shape under the mouse and the last shape which 00057 * receive mouse event. 00058 * 00059 * - If the mouse is on any shape, 00060 * - If the new shape is the same as the last shape, we will send the 00061 * EVT_MOUSE_MOVE events to it to notify it the mouse is moving inside it. 00062 * - If the new shape is not the same as the last shape, we will send the 00063 * EVT_MOUSE_OVER to notify it the mouse is just touch it. 00064 * - If the current shape is not the same as the last shape, send the 00065 * EVT_MOUSE_OUT to the last shape to tell it the mouse have left it. 00066 * \code 00067 * mevt = (XMotionEvent *)&evt; 00068 * x = mevt->x; 00069 * y = mevt->y; 00070 * state = get_button_state(mevt->state); 00071 * 00072 * shape = find_shape_at_pos(rdman, x, y, 00073 * &in_stroke); 00074 * if(shape != NULL) { 00075 * if(rt->last != shape) { 00076 * if(rt->last) 00077 * notify_shapes(rdman, rt->last, x, y, 00078 * EVT_MOUSE_OUT, state, 0); 00079 * notify_shapes(rdman, shape, x, y, 00080 * EVT_MOUSE_OVER, state, 0); 00081 * rt->last = shape; 00082 * } else 00083 * notify_shapes(rdman, shape, x, y, 00084 * EVT_MOUSE_MOVE, state, 0); 00085 * } else { 00086 * if(rt->last) { 00087 * notify_shapes(rdman, rt->last, x, y, 00088 * EVT_MOUSE_OUT, state, 0); 00089 * rt->last = NULL; 00090 * } 00091 * } 00092 * \endcode 00093 * 00094 * Please remember that the subject will relay the the events to all of 00095 * its parents. 00096 * 00097 * PS. Currently, the MadButterfly does not have mechanism to stop 00098 * propogation based on the result of the observer. 00099 * 00100 * \section evt_key Key event 00101 * 00102 * The key events is send as subject type OBJT_KB. Each key object has 00103 * the following fields code: The original raw keycode. sym: The symbol ID 00104 * of the raw keycode. * event.type: EVT_KB_PRESS or EVT_KB_RELEASE 00105 * 00106 * \section evt_timer Timer event 00107 * 00108 * The timer use different mechanism. It does not use the observer pattern. 00109 * Instead, it is registered as separate timer queue. Do we want to change 00110 * the implementation? 00111 * 00112 * \section evt_io IO event 00113 * 00114 * Currently, no IO events is available in the MadButterfly yet. W should 00115 * add the following IO subjects. OBJT_FD: We need to provide some function 00116 * to generate subject for file description. It will send events when teh 00117 * file descriptor become available for read/write or error. OBJT_XMLIO: 00118 * Provides functions similiar to the XMLSocket in actionscript. 00119 * 00120 * \section evt_repaint Repaint 00121 * 00122 * The repaint event is not sent directly. Instead, the X backend call 00123 * rdman_redraw_area directly to handle the repaint event. This function 00124 * will send EVT_RDMAN_REDRAW out. 00125 * 00126 * \section evt_summary Summary 00127 * 00128 * The observer pattern can be used to be the abstraction layer of the 00129 * MadButterfly. The current implementation has effectively seperate the 00130 * backend and the core engine. There is no direct call to the engine 00131 * from the backend. All messages are deliver to the MadButterfly through 00132 * the observer. 00133 */