release 0.8.0
[swfdec.git] / swfdec / swfdec_event.c
blob98ff50564d6708c712894b3b5d4d51c5684b0eb9
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_script_internal.h"
29 typedef struct _SwfdecEvent SwfdecEvent;
31 struct _SwfdecEvent {
32 guint conditions;
33 guint8 key;
34 SwfdecScript *script;
37 struct _SwfdecEventList {
38 guint refcount;
39 GArray * events;
42 /**
43 * swfdec_event_type_get_name:
44 * @type: a #SwfdecEventType
46 * Gets the name for the event as a refcounted string or %NULL if the
47 * given clip event has no associated event.
49 * Returns: The name of the event or %NULL if none.
50 **/
51 const char *
52 swfdec_event_type_get_name (SwfdecEventType type)
54 switch (type) {
55 case SWFDEC_EVENT_LOAD:
56 return SWFDEC_AS_STR_onLoad;
57 case SWFDEC_EVENT_ENTER:
58 return SWFDEC_AS_STR_onEnterFrame;
59 case SWFDEC_EVENT_UNLOAD:
60 return SWFDEC_AS_STR_onUnload;
61 case SWFDEC_EVENT_MOUSE_MOVE:
62 return SWFDEC_AS_STR_onMouseMove;
63 case SWFDEC_EVENT_MOUSE_DOWN:
64 return SWFDEC_AS_STR_onMouseDown;
65 case SWFDEC_EVENT_MOUSE_UP:
66 return SWFDEC_AS_STR_onMouseUp;
67 case SWFDEC_EVENT_KEY_UP:
68 return SWFDEC_AS_STR_onKeyUp;
69 case SWFDEC_EVENT_KEY_DOWN:
70 return SWFDEC_AS_STR_onKeyDown;
71 case SWFDEC_EVENT_DATA:
72 return SWFDEC_AS_STR_onData;
73 case SWFDEC_EVENT_INITIALIZE:
74 return NULL;
75 case SWFDEC_EVENT_PRESS:
76 return SWFDEC_AS_STR_onPress;
77 case SWFDEC_EVENT_RELEASE:
78 return SWFDEC_AS_STR_onRelease;
79 case SWFDEC_EVENT_RELEASE_OUTSIDE:
80 return SWFDEC_AS_STR_onReleaseOutside;
81 case SWFDEC_EVENT_ROLL_OVER:
82 return SWFDEC_AS_STR_onRollOver;
83 case SWFDEC_EVENT_ROLL_OUT:
84 return SWFDEC_AS_STR_onRollOut;
85 case SWFDEC_EVENT_DRAG_OVER:
86 return SWFDEC_AS_STR_onDragOver;
87 case SWFDEC_EVENT_DRAG_OUT:
88 return SWFDEC_AS_STR_onDragOut;
89 case SWFDEC_EVENT_KEY_PRESS:
90 return NULL;
91 case SWFDEC_EVENT_CONSTRUCT:
92 return SWFDEC_AS_STR_onConstruct;
93 case SWFDEC_EVENT_CHANGED:
94 return SWFDEC_AS_STR_onChanged;
95 case SWFDEC_EVENT_SCROLL:
96 return SWFDEC_AS_STR_onScroller;
97 default:
98 g_assert_not_reached ();
99 return NULL;
103 SwfdecEventList *
104 swfdec_event_list_new (void)
106 SwfdecEventList *list;
108 list = g_new0 (SwfdecEventList, 1);
109 list->refcount = 1;
110 list->events = g_array_new (FALSE, FALSE, sizeof (SwfdecEvent));
112 return list;
115 /* FIXME: this is a bit nasty because of modifying */
116 SwfdecEventList *
117 swfdec_event_list_copy (SwfdecEventList *list)
119 g_return_val_if_fail (list != NULL, NULL);
120 g_return_val_if_fail (list->refcount > 0, NULL);
122 list->refcount++;
124 return list;
127 void
128 swfdec_event_list_free (SwfdecEventList *list)
130 guint i;
132 g_return_if_fail (list != NULL);
133 g_return_if_fail (list->refcount > 0);
135 list->refcount--;
136 if (list->refcount > 0)
137 return;
139 for (i = 0; i < list->events->len; i++) {
140 SwfdecEvent *event = &g_array_index (list->events, SwfdecEvent, i);
141 swfdec_script_unref (event->script);
143 g_array_free (list->events, TRUE);
144 g_free (list);
147 #define N_CONDITIONS 19
148 void
149 swfdec_event_list_parse (SwfdecEventList *list, SwfdecBits *bits, int version,
150 guint conditions, guint8 key, const char *description)
152 SwfdecEvent event;
153 char *name;
154 guint i;
156 g_return_if_fail (list != NULL);
157 g_return_if_fail (list->refcount == 1);
158 g_return_if_fail (description != NULL);
160 event.conditions = conditions & SWFDEC_EVENT_MASK;
161 event.key = key;
162 i = g_bit_nth_lsf (conditions, -1);
163 name = g_strconcat (description, ".", i < N_CONDITIONS ?
164 swfdec_event_type_get_name (i) : "???", NULL);
165 event.script = swfdec_script_new_from_bits (bits, name, version);
166 g_free (name);
167 if (event.script)
168 g_array_append_val (list->events, event);
171 void
172 swfdec_event_list_execute (SwfdecEventList *list, SwfdecAsObject *object,
173 guint condition, guint8 key)
175 guint i;
177 g_return_if_fail (list != NULL);
178 g_return_if_fail (SWFDEC_IS_AS_OBJECT (object));
179 g_return_if_fail (condition < N_CONDITIONS);
181 condition = (1 << condition);
182 /* FIXME: Do we execute all events if the event list is gone already? */
183 /* need to ref here because followup code could free all references to the list */
184 list = swfdec_event_list_copy (list);
185 for (i = 0; i < list->events->len; i++) {
186 SwfdecEvent *event = &g_array_index (list->events, SwfdecEvent, i);
187 if ((event->conditions & condition) &&
188 (condition != 1 << SWFDEC_EVENT_KEY_DOWN || event->key == key)) {
189 SWFDEC_LOG ("executing script for event %u on scriptable %p", condition, object);
190 swfdec_as_object_run (object, event->script);
193 swfdec_event_list_free (list);
196 gboolean
197 swfdec_event_list_has_conditions (SwfdecEventList *list, SwfdecAsObject *object,
198 guint condition, guint8 key)
200 guint i;
202 g_return_val_if_fail (list != NULL, FALSE);
203 g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), FALSE);
204 g_return_val_if_fail (condition < N_CONDITIONS, FALSE);
206 condition = 1 << condition;
207 for (i = 0; i < list->events->len; i++) {
208 SwfdecEvent *event = &g_array_index (list->events, SwfdecEvent, i);
209 if ((event->conditions & condition) &&
210 event->key == key)
211 return TRUE;
213 return FALSE;
216 #define MOUSE_EVENTS 0x1FC0
217 gboolean
218 swfdec_event_list_has_mouse_events (SwfdecEventList *list)
220 guint i;
222 g_return_val_if_fail (list != NULL, FALSE);
224 for (i = 0; i < list->events->len; i++) {
225 SwfdecEvent *event = &g_array_index (list->events, SwfdecEvent, i);
226 if (event->conditions & MOUSE_EVENTS)
227 return TRUE;
229 return FALSE;