implement mouse_events vfunc
[swfdec.git] / libswfdec / swfdec_event.c
blob585a5e0cfdc47eceee3a075f4dd94bfbdc2b89a2
1 /* Swfdec
2 * Copyright (C) 2006 Benjamin Otte <otte@gnome.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 #include "swfdec_event.h"
24 #include "swfdec_as_internal.h"
25 #include "swfdec_as_strings.h"
26 #include "swfdec_debug.h"
27 #include "swfdec_player_internal.h"
28 #include "swfdec_script_internal.h"
30 typedef struct _SwfdecEvent SwfdecEvent;
32 struct _SwfdecEvent {
33 guint conditions;
34 guint8 key;
35 SwfdecScript *script;
38 struct _SwfdecEventList {
39 SwfdecPlayer * player;
40 guint refcount;
41 GArray * events;
44 /**
45 * swfdec_event_type_get_name:
46 * @type: a #SwfdecEventType
48 * Gets the name for the event as a refcounted string or %NULL if the
49 * given clip event has no associated event.
51 * Returns: The name of the event or %NULL if none.
52 **/
53 const char *
54 swfdec_event_type_get_name (SwfdecEventType type)
56 switch (type) {
57 case SWFDEC_EVENT_LOAD:
58 return SWFDEC_AS_STR_onLoad;
59 case SWFDEC_EVENT_ENTER:
60 return SWFDEC_AS_STR_onEnterFrame;
61 case SWFDEC_EVENT_UNLOAD:
62 return SWFDEC_AS_STR_onUnload;
63 case SWFDEC_EVENT_MOUSE_MOVE:
64 return SWFDEC_AS_STR_onMouseMove;
65 case SWFDEC_EVENT_MOUSE_DOWN:
66 return SWFDEC_AS_STR_onMouseDown;
67 case SWFDEC_EVENT_MOUSE_UP:
68 return SWFDEC_AS_STR_onMouseUp;
69 case SWFDEC_EVENT_KEY_UP:
70 return SWFDEC_AS_STR_onKeyUp;
71 case SWFDEC_EVENT_KEY_DOWN:
72 return SWFDEC_AS_STR_onKeyDown;
73 case SWFDEC_EVENT_DATA:
74 return SWFDEC_AS_STR_onData;
75 case SWFDEC_EVENT_INITIALIZE:
76 return NULL;
77 case SWFDEC_EVENT_PRESS:
78 return SWFDEC_AS_STR_onPress;
79 case SWFDEC_EVENT_RELEASE:
80 return SWFDEC_AS_STR_onRelease;
81 case SWFDEC_EVENT_RELEASE_OUTSIDE:
82 return SWFDEC_AS_STR_onReleaseOutside;
83 case SWFDEC_EVENT_ROLL_OVER:
84 return SWFDEC_AS_STR_onRollOver;
85 case SWFDEC_EVENT_ROLL_OUT:
86 return SWFDEC_AS_STR_onRollOut;
87 case SWFDEC_EVENT_DRAG_OVER:
88 return SWFDEC_AS_STR_onDragOver;
89 case SWFDEC_EVENT_DRAG_OUT:
90 return SWFDEC_AS_STR_onDragOut;
91 case SWFDEC_EVENT_KEY_PRESS:
92 return NULL;
93 case SWFDEC_EVENT_CONSTRUCT:
94 return SWFDEC_AS_STR_onConstruct;
95 default:
96 g_assert_not_reached ();
97 return NULL;
101 SwfdecEventList *
102 swfdec_event_list_new (SwfdecPlayer *player)
104 SwfdecEventList *list;
106 g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL);
108 list = g_new0 (SwfdecEventList, 1);
109 list->player = player;
110 list->refcount = 1;
111 list->events = g_array_new (FALSE, FALSE, sizeof (SwfdecEvent));
113 return list;
116 /* FIXME: this is a bit nasty because of modifying */
117 SwfdecEventList *
118 swfdec_event_list_copy (SwfdecEventList *list)
120 g_return_val_if_fail (list != NULL, NULL);
121 g_return_val_if_fail (list->refcount > 0, NULL);
123 list->refcount++;
125 return list;
128 void
129 swfdec_event_list_free (SwfdecEventList *list)
131 guint i;
133 g_return_if_fail (list != NULL);
134 g_return_if_fail (list->refcount > 0);
136 list->refcount--;
137 if (list->refcount > 0)
138 return;
140 for (i = 0; i < list->events->len; i++) {
141 SwfdecEvent *event = &g_array_index (list->events, SwfdecEvent, i);
142 swfdec_script_unref (event->script);
144 g_array_free (list->events, TRUE);
145 g_free (list);
148 #define N_CONDITIONS 19
149 void
150 swfdec_event_list_parse (SwfdecEventList *list, SwfdecBits *bits, int version,
151 guint conditions, guint8 key, const char *description)
153 SwfdecEvent event;
154 char *name;
155 guint i;
157 g_return_if_fail (list != NULL);
158 g_return_if_fail (list->refcount == 1);
159 g_return_if_fail (description != NULL);
161 event.conditions = conditions;
162 event.key = key;
163 i = g_bit_nth_lsf (conditions, -1);
164 name = g_strconcat (description, ".", i < N_CONDITIONS ?
165 swfdec_event_type_get_name (i) : "???", NULL);
166 event.script = swfdec_script_new_from_bits (bits, name, version);
167 g_free (name);
168 if (event.script)
169 g_array_append_val (list->events, event);
172 void
173 swfdec_event_list_execute (SwfdecEventList *list, SwfdecAsObject *object,
174 SwfdecSecurity *sec, guint condition, guint8 key)
176 guint i;
178 g_return_if_fail (list != NULL);
179 g_return_if_fail (SWFDEC_IS_AS_OBJECT (object));
180 g_return_if_fail (SWFDEC_IS_SECURITY (sec));
181 g_return_if_fail (condition < N_CONDITIONS);
183 condition = (1 << condition);
184 /* FIXME: Do we execute all events if the event list is gone already? */
185 /* need to ref here because followup code could free all references to the list */
186 list = swfdec_event_list_copy (list);
187 for (i = 0; i < list->events->len; i++) {
188 SwfdecEvent *event = &g_array_index (list->events, SwfdecEvent, i);
189 if ((event->conditions & condition) &&
190 event->key == key) {
191 SWFDEC_LOG ("executing script for event %u on scriptable %p", condition, object);
192 swfdec_as_object_run_with_security (object, event->script, sec);
195 swfdec_event_list_free (list);
198 gboolean
199 swfdec_event_list_has_conditions (SwfdecEventList *list, SwfdecAsObject *object,
200 guint condition, guint8 key)
202 guint i;
204 g_return_val_if_fail (list != NULL, FALSE);
205 g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), FALSE);
206 g_return_val_if_fail (condition < N_CONDITIONS, FALSE);
208 condition = 1 << condition;
209 for (i = 0; i < list->events->len; i++) {
210 SwfdecEvent *event = &g_array_index (list->events, SwfdecEvent, i);
211 if ((event->conditions & condition) &&
212 event->key == key)
213 return TRUE;
215 return FALSE;
218 #define MOUSE_EVENTS 0x1FC0
219 gboolean
220 swfdec_event_list_has_mouse_events (SwfdecEventList *list)
222 guint i;
224 g_return_val_if_fail (list != NULL, FALSE);
226 for (i = 0; i < list->events->len; i++) {
227 SwfdecEvent *event = &g_array_index (list->events, SwfdecEvent, i);
228 if (event->conditions & MOUSE_EVENTS)
229 return TRUE;
231 return FALSE;