1 /*
2 * This file is part of libdom.
3 * Licensed under the MIT License,
4 * http://www.opensource.org/licenses/mit-license.php
5 * Copyright 2009 Bo Yang <struggleyb.nku@gmail.com>
6 */
7
8 #include <stdlib.h>
9 #include <string.h>
10
11 #include "events/mouse_event.h"
12 #include "core/document.h"
13
14 #include "utils/utils.h"
15
16 static void _virtual_dom_mouse_event_destroy(struct dom_event *evt);
17
18 static struct dom_event_private_vtable _event_vtable = {
19 _virtual_dom_mouse_event_destroy
20 };
21
22 /* Constructor */
_dom_mouse_event_create(struct dom_mouse_event ** evt)23 dom_exception _dom_mouse_event_create(struct dom_mouse_event **evt)
24 {
25 *evt = malloc(sizeof(dom_mouse_event));
26 if (*evt == NULL)
27 return DOM_NO_MEM_ERR;
28
29 ((struct dom_event *) *evt)->vtable = &_event_vtable;
30
31 return _dom_mouse_event_initialise(*evt);
32 }
33
34 /* Destructor */
_dom_mouse_event_destroy(struct dom_mouse_event * evt)35 void _dom_mouse_event_destroy(struct dom_mouse_event *evt)
36 {
37 _dom_mouse_event_finalise((dom_ui_event *) evt);
38
39 free(evt);
40 }
41
42 /* Initialise function */
_dom_mouse_event_initialise(struct dom_mouse_event * evt)43 dom_exception _dom_mouse_event_initialise(struct dom_mouse_event *evt)
44 {
45 evt->modifier_state = 0;
46
47 return _dom_ui_event_initialise((dom_ui_event *) evt);
48 }
49
50 /* The virtual destroy function */
_virtual_dom_mouse_event_destroy(struct dom_event * evt)51 void _virtual_dom_mouse_event_destroy(struct dom_event *evt)
52 {
53 _dom_mouse_event_destroy((dom_mouse_event *) evt);
54 }
55
56 /*----------------------------------------------------------------------*/
57 /* The public API */
58
59 /**
60 * Get screenX
61 *
62 * \param evt The Event object
63 * \param x The returned screenX
64 * \return DOM_NO_ERR.
65 */
_dom_mouse_event_get_screen_x(dom_mouse_event * evt,int32_t * x)66 dom_exception _dom_mouse_event_get_screen_x(dom_mouse_event *evt,
67 int32_t *x)
68 {
69 *x = evt->sx;
70
71 return DOM_NO_ERR;
72 }
73
74 /**
75 * Get screenY
76 *
77 * \param evt The Event object
78 * \param y The returned screenY
79 * \return DOM_NO_ERR.
80 */
_dom_mouse_event_get_screen_y(dom_mouse_event * evt,int32_t * y)81 dom_exception _dom_mouse_event_get_screen_y(dom_mouse_event *evt,
82 int32_t *y)
83 {
84 *y = evt->sy;
85
86 return DOM_NO_ERR;
87 }
88
89 /**
90 * Get clientX
91 *
92 * \param evt The Event object
93 * \param x The returned clientX
94 * \return DOM_NO_ERR.
95 */
_dom_mouse_event_get_client_x(dom_mouse_event * evt,int32_t * x)96 dom_exception _dom_mouse_event_get_client_x(dom_mouse_event *evt,
97 int32_t *x)
98 {
99 *x = evt->cx;
100
101 return DOM_NO_ERR;
102 }
103
104 /**
105 * Get clientY
106 *
107 * \param evt The Event object
108 * \param y The returned clientY
109 * \return DOM_NO_ERR.
110 */
_dom_mouse_event_get_client_y(dom_mouse_event * evt,int32_t * y)111 dom_exception _dom_mouse_event_get_client_y(dom_mouse_event *evt,
112 int32_t *y)
113 {
114 *y = evt->cy;
115
116 return DOM_NO_ERR;
117 }
118
119 /**
120 * Get the ctrl key state
121 *
122 * \param evt The Event object
123 * \param key Whether the Control key is pressed down
124 * \return DOM_NO_ERR.
125 */
_dom_mouse_event_get_ctrl_key(dom_mouse_event * evt,bool * key)126 dom_exception _dom_mouse_event_get_ctrl_key(dom_mouse_event *evt,
127 bool *key)
128 {
129 *key = ((evt->modifier_state & DOM_MOD_CTRL) != 0);
130
131 return DOM_NO_ERR;
132 }
133
134 /**
135 * Get the shift key state
136 *
137 * \param evt The Event object
138 * \param key Whether the Shift key is pressed down
139 * \return DOM_NO_ERR.
140 */
_dom_mouse_event_get_shift_key(dom_mouse_event * evt,bool * key)141 dom_exception _dom_mouse_event_get_shift_key(dom_mouse_event *evt,
142 bool *key)
143 {
144 *key = ((evt->modifier_state & DOM_MOD_SHIFT) != 0);
145
146 return DOM_NO_ERR;
147 }
148
149 /**
150 * Get the alt key state
151 *
152 * \param evt The Event object
153 * \param key Whether the Alt key is pressed down
154 * \return DOM_NO_ERR.
155 */
_dom_mouse_event_get_alt_key(dom_mouse_event * evt,bool * key)156 dom_exception _dom_mouse_event_get_alt_key(dom_mouse_event *evt,
157 bool *key)
158 {
159 *key = ((evt->modifier_state & DOM_MOD_ALT) != 0);
160
161 return DOM_NO_ERR;
162 }
163
164 /**
165 * Get the meta key state
166 *
167 * \param evt The Event object
168 * \param key Whether the Meta key is pressed down
169 * \return DOM_NO_ERR.
170 */
_dom_mouse_event_get_meta_key(dom_mouse_event * evt,bool * key)171 dom_exception _dom_mouse_event_get_meta_key(dom_mouse_event *evt,
172 bool *key)
173 {
174 *key = ((evt->modifier_state & DOM_MOD_META) != 0);
175
176 return DOM_NO_ERR;
177 }
178
179 /**
180 * Get the button which get pressed
181 *
182 * \param evt The Event object
183 * \param button The pressed mouse button
184 * \return DOM_NO_ERR.
185 */
_dom_mouse_event_get_button(dom_mouse_event * evt,unsigned short * button)186 dom_exception _dom_mouse_event_get_button(dom_mouse_event *evt,
187 unsigned short *button)
188 {
189 *button = evt->button;
190
191 return DOM_NO_ERR;
192 }
193
194 /**
195 * Get the related target
196 *
197 * \param evt The Event object
198 * \param et The related EventTarget
199 * \return DOM_NO_ERR.
200 */
_dom_mouse_event_get_related_target(dom_mouse_event * evt,dom_event_target ** et)201 dom_exception _dom_mouse_event_get_related_target(dom_mouse_event *evt,
202 dom_event_target **et)
203 {
204 *et = evt->related_target;
205
206 return DOM_NO_ERR;
207 }
208
209 /**
210 * Query the state of a modifier using a key identifier
211 *
212 * \param evt The event object
213 * \param ml The modifier identifier, such as "Alt", "Control", "Meta",
214 * "AltGraph", "CapsLock", "NumLock", "Scroll", "Shift".
215 * \param state Whether the modifier key is pressed
216 * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
217 *
218 * @note: If an application wishes to distinguish between right and left
219 * modifiers, this information could be deduced using keyboard events and
220 * KeyboardEvent.keyLocation.
221 */
_dom_mouse_event_get_modifier_state(dom_mouse_event * evt,dom_string * m,bool * state)222 dom_exception _dom_mouse_event_get_modifier_state(dom_mouse_event *evt,
223 dom_string *m, bool *state)
224 {
225 const char *data;
226 size_t len;
227
228 if (m == NULL) {
229 *state = false;
230 return DOM_NO_ERR;
231 }
232
233 data = dom_string_data(m);
234 len = dom_string_byte_length(m);
235
236 if (len == SLEN("AltGraph") && strncmp(data, "AltGraph", len) == 0) {
237 *state = ((evt->modifier_state & DOM_MOD_ALT_GRAPH) != 0);
238 } else if (len == SLEN("Alt") && strncmp(data, "Alt", len) == 0) {
239 *state = ((evt->modifier_state & DOM_MOD_ALT) != 0);
240 } else if (len == SLEN("CapsLock") &&
241 strncmp(data, "CapsLock", len) == 0) {
242 *state = ((evt->modifier_state & DOM_MOD_CAPS_LOCK) != 0);
243 } else if (len == SLEN("Control") &&
244 strncmp(data, "Control", len) == 0) {
245 *state = ((evt->modifier_state & DOM_MOD_CTRL) != 0);
246 } else if (len == SLEN("Meta") && strncmp(data, "Meta", len) == 0) {
247 *state = ((evt->modifier_state & DOM_MOD_META) != 0);
248 } else if (len == SLEN("NumLock") &&
249 strncmp(data, "NumLock", len) == 0) {
250 *state = ((evt->modifier_state & DOM_MOD_NUM_LOCK) != 0);
251 } else if (len == SLEN("Scroll") &&
252 strncmp(data, "Scroll", len) == 0) {
253 *state = ((evt->modifier_state & DOM_MOD_SCROLL) != 0);
254 } else if (len == SLEN("Shift") && strncmp(data, "Shift", len) == 0) {
255 *state = ((evt->modifier_state & DOM_MOD_SHIFT) != 0);
256 }
257
258 return DOM_NO_ERR;
259 }
260
261 /**
262 * Initialise this mouse event
263 *
264 * \param evt The Event object
265 * \param type The event's type
266 * \param bubble Whether this is a bubbling event
267 * \param cancelable Whether this is a cancelable event
268 * \param view The AbstractView associated with this event
269 * \param detail The detail information of this mouse event
270 * \param screen_x The x position of the mouse pointer in screen
271 * \param screen_y The y position of the mouse pointer in screen
272 * \param client_x The x position of the mouse pointer in client window
273 * \param client_y The y position of the mouse pointer in client window
274 * \param alt The state of Alt key, true for pressed, false otherwise
275 * \param shift The state of Shift key, true for pressed, false otherwise
276 * \param mata The state of Meta key, true for pressed, false otherwise
277 * \param button The mouse button pressed
278 * \param et The related target of this event, may be NULL
279 * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
280 */
_dom_mouse_event_init(dom_mouse_event * evt,dom_string * type,bool bubble,bool cancelable,struct dom_abstract_view * view,int32_t detail,int32_t screen_x,int32_t screen_y,int32_t client_x,int32_t client_y,bool ctrl,bool alt,bool shift,bool meta,unsigned short button,dom_event_target * et)281 dom_exception _dom_mouse_event_init(dom_mouse_event *evt,
282 dom_string *type, bool bubble, bool cancelable,
283 struct dom_abstract_view *view, int32_t detail, int32_t screen_x,
284 int32_t screen_y, int32_t client_x, int32_t client_y, bool ctrl,
285 bool alt, bool shift, bool meta, unsigned short button,
286 dom_event_target *et)
287 {
288 evt->sx = screen_x;
289 evt->sy = screen_y;
290 evt->cx = client_x;
291 evt->cy = client_y;
292
293 evt->modifier_state = 0;
294 if (ctrl == true) {
295 evt->modifier_state = evt->modifier_state | DOM_MOD_CTRL;
296 }
297 if (alt == true) {
298 evt->modifier_state = evt->modifier_state | DOM_MOD_ALT;
299 }
300 if (shift == true) {
301 evt->modifier_state = evt->modifier_state | DOM_MOD_SHIFT;
302 }
303 if (meta == true) {
304 evt->modifier_state = evt->modifier_state | DOM_MOD_META;
305 }
306
307 evt->button = button;
308 evt->related_target = et;
309
310 return _dom_ui_event_init(&evt->base, type, bubble, cancelable, view,
311 detail);
312 }
313
314 /**
315 * Initialise the event with namespace
316 *
317 * \param evt The Event object
318 * \param namespace The namespace of this event
319 * \param type The event's type
320 * \param bubble Whether this is a bubbling event
321 * \param cancelable Whether this is a cancelable event
322 * \param view The AbstractView associated with this event
323 * \param detail The detail information of this mouse event
324 * \param screen_x The x position of the mouse pointer in screen
325 * \param screen_y The y position of the mouse pointer in screen
326 * \param client_x The x position of the mouse pointer in client window
327 * \param client_y The y position of the mouse pointer in client window
328 * \param alt The state of Alt key, true for pressed, false otherwise
329 * \param shift The state of Shift key, true for pressed, false otherwise
330 * \param mata The state of Meta key, true for pressed, false otherwise
331 * \param button The mouse button pressed
332 * \param et The related target of this event, may be NULL
333 * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
334 */
_dom_mouse_event_init_ns(dom_mouse_event * evt,dom_string * namespace,dom_string * type,bool bubble,bool cancelable,struct dom_abstract_view * view,int32_t detail,int32_t screen_x,int32_t screen_y,int32_t client_x,int32_t client_y,bool ctrl,bool alt,bool shift,bool meta,unsigned short button,dom_event_target * et)335 dom_exception _dom_mouse_event_init_ns(dom_mouse_event *evt,
336 dom_string *namespace, dom_string *type,
337 bool bubble, bool cancelable, struct dom_abstract_view *view,
338 int32_t detail, int32_t screen_x, int32_t screen_y, int32_t client_x,
339 int32_t client_y, bool ctrl, bool alt, bool shift, bool meta,
340 unsigned short button, dom_event_target *et)
341 {
342 evt->sx = screen_x;
343 evt->sy = screen_y;
344 evt->cx = client_x;
345 evt->cy = client_y;
346
347 evt->modifier_state = 0;
348 if (ctrl == true) {
349 evt->modifier_state = evt->modifier_state | DOM_MOD_CTRL;
350 }
351 if (alt == true) {
352 evt->modifier_state = evt->modifier_state | DOM_MOD_ALT;
353 }
354 if (shift == true) {
355 evt->modifier_state = evt->modifier_state | DOM_MOD_SHIFT;
356 }
357 if (meta == true) {
358 evt->modifier_state = evt->modifier_state | DOM_MOD_META;
359 }
360
361 evt->button = button;
362 evt->related_target = et;
363
364 return _dom_ui_event_init_ns(&evt->base, namespace, type, bubble,
365 cancelable, view, detail);
366 }
367
368