root/trunk/showtime/src/event.c @ 4208

Revision 4208, 7.9 KB (checked in by andoma, 7 months ago)

Add displaying of some stats when playing video

Line 
1/*
2 *  Input handling
3 *  Copyright (C) 2007 Andreas Öman
4 *
5 *  This program is free software: you can redistribute it and/or modify
6 *  it under the terms of the GNU General Public License as published by
7 *  the Free Software Foundation, either version 3 of the License, or
8 *  (at your option) any later version.
9 *
10 *  This program is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 *  GNU General Public License for more details.
14 *
15 *  You should have received a copy of the GNU General Public License
16 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <sys/time.h>
20#include <errno.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <unistd.h>
24#include <string.h>
25#include <assert.h>
26
27#include "showtime.h"
28#include "event.h"
29#include "misc/strtab.h"
30#include "prop.h"
31
32/**
33 *
34 */
35static void
36event_default_dtor(event_t *e)
37{
38  free(e);
39}
40
41/**
42 *
43 */
44void *
45event_create(event_type_t type, size_t size)
46{
47  event_t *e = malloc(size);
48  e->e_dtor = event_default_dtor;
49  e->e_refcount = 1;
50  e->e_mapped = 0;
51  assert(type > EVENT_OFFSET);
52  e->e_type_x = type;
53  return e;
54}
55
56/**
57 *
58 */
59void *
60event_create_unicode(int sym)
61{
62  event_unicode_t *e = malloc(sizeof(event_unicode_t));
63  e->h.e_dtor = event_default_dtor;
64  e->h.e_refcount = 1;
65  e->h.e_mapped = 0;
66  e->h.e_type_x = EVENT_UNICODE;
67  e->sym = sym;
68  return e;
69}
70
71
72/**
73 *
74 */
75void
76event_enqueue(event_queue_t *eq, event_t *e)
77{
78  atomic_add(&e->e_refcount, 1);
79  hts_mutex_lock(&eq->eq_mutex);
80  TAILQ_INSERT_TAIL(&eq->eq_q, e, e_link);
81  hts_cond_signal(&eq->eq_cond);
82  hts_mutex_unlock(&eq->eq_mutex);
83}
84
85
86/**
87 *
88 * @param timeout Timeout in milliseconds
89 */
90event_t *
91event_get(event_queue_t *eq)
92{
93  event_t *e;
94
95  hts_mutex_lock(&eq->eq_mutex);
96
97  while((e = TAILQ_FIRST(&eq->eq_q)) == NULL)
98    hts_cond_wait(&eq->eq_cond, &eq->eq_mutex);
99
100  TAILQ_REMOVE(&eq->eq_q, e, e_link);
101  hts_mutex_unlock(&eq->eq_mutex);
102  return e;
103}
104
105
106/**
107 *
108 */
109void
110event_unref(event_t *e)
111{
112  if(atomic_add(&e->e_refcount, -1) == 1)
113    e->e_dtor(e);
114}
115
116
117/**
118 *
119 */
120void
121event_initqueue(event_queue_t *eq)
122{
123  TAILQ_INIT(&eq->eq_q);
124  hts_cond_init(&eq->eq_cond);
125  hts_mutex_init(&eq->eq_mutex);
126}
127
128
129/**
130 *
131 */
132void
133event_flushqueue(event_queue_t *eq)
134{
135  event_t *e;
136
137  hts_mutex_lock(&eq->eq_mutex);
138
139  while((e = TAILQ_FIRST(&eq->eq_q)) != NULL) {
140    TAILQ_REMOVE(&eq->eq_q, e, e_link);
141    event_unref(e);
142  }
143  hts_mutex_unlock(&eq->eq_mutex);
144}
145
146
147/**
148 *
149 */
150static struct strtab actionnames[] = {
151  { "Up",                    ACTION_UP },
152  { "Down",                  ACTION_DOWN },
153  { "Left",                  ACTION_LEFT },
154  { "Right",                 ACTION_RIGHT },
155  { "Enter",                 ACTION_ENTER },
156  { "PageUp",                ACTION_PAGE_UP },
157  { "PageDown",              ACTION_PAGE_DOWN },
158  { "Top",                   ACTION_TOP },
159  { "Bottom",                ACTION_BOTTOM },
160  { "Close",                 ACTION_CLOSE },
161  { "Stop",                  ACTION_STOP },
162  { "PlayPause",             ACTION_PLAYPAUSE },
163  { "Play",                  ACTION_PLAY },
164  { "Pause",                 ACTION_PAUSE },
165  { "VolumeUp",              ACTION_VOLUME_UP },
166  { "VolumeDown",            ACTION_VOLUME_DOWN },
167  { "VolumeMuteToggle",      ACTION_VOLUME_MUTE_TOGGLE },
168  { "Menu",                  ACTION_MENU },
169  { "Back",                  ACTION_NAV_BACK },
170  { "Forward",               ACTION_NAV_FWD },
171  { "Select",                ACTION_SELECT },
172  { "Eject",                 ACTION_EJECT },
173  { "Sleep",                 ACTION_SLEEP },
174  { "PreviousTrack",         ACTION_PREV_TRACK },
175  { "NextTrack",             ACTION_NEXT_TRACK },
176  { "SeekForward",           ACTION_SEEK_FORWARD },
177  { "SeekReverse",           ACTION_SEEK_BACKWARD },
178  { "Quit",                  ACTION_QUIT },
179  { "Home",                  ACTION_HOME },
180  { "ChangeView",            ACTION_SWITCH_VIEW },
181  { "Channel+",              ACTION_CHANNEL_NEXT },
182  { "Channel-",              ACTION_CHANNEL_PREV },
183  { "FullscreenToggle",      ACTION_FULLSCREEN_TOGGLE },
184  { "Increase",              ACTION_INCR },
185  { "Decrease",              ACTION_DECR },
186  { "MediaStats",            ACTION_SHOW_MEDIA_STATS },
187};
188
189
190
191const char *
192action_code2str(action_type_t code)
193{
194  return val2str(code, actionnames);
195}
196
197action_type_t
198action_str2code(const char *str)
199{
200  return str2val(str, actionnames);
201}
202
203/**
204 *
205 */
206event_t *
207event_create_url(event_type_t et, const char *url)
208{
209  int l = strlen(url) + 1;
210  event_t *e = event_create(et, sizeof(event_t) + l);
211  memcpy(e->e_payload, url, l);
212  return e;
213}
214
215
216/**
217 *
218 */
219static void
220event_openurl2_dtor(event_t *e)
221{
222  event_openurl_t *ou = (void *)e;
223  free(ou->url);
224  free(ou->type);
225  free(ou->parent);
226  free(ou);
227}
228
229
230/**
231 *
232 */
233event_t *
234event_create_openurl(const char *url, const char *type, const char *parent)
235{
236  event_openurl_t *e = event_create(EVENT_OPENURL, sizeof(event_openurl_t));
237
238  e->url      = url    ? strdup(url)    : NULL;
239  e->type     = type   ? strdup(type)   : NULL;
240  e->parent   = parent ? strdup(parent) : NULL;
241  e->h.e_dtor = event_openurl2_dtor;
242  return &e->h;
243}
244
245
246/**
247 *
248 */
249int
250action_update_hold_by_event(int hold, event_t *e)
251{
252  if(event_is_action(e, ACTION_PLAYPAUSE))
253    return !hold;
254 
255  if(event_is_action(e, ACTION_PAUSE))
256    return 1;
257
258  if(event_is_action(e, ACTION_PLAY))
259    return 0;
260
261  return 0;
262}
263
264
265/**
266 *
267 */
268event_t *
269event_create_action_multi(const action_type_t *actions, size_t numactions)
270{
271  event_action_vector_t *eav;
272  int s = sizeof(action_type_t) * numactions;
273
274  eav = event_create(EVENT_ACTION_VECTOR, sizeof(event_action_vector_t) + s);
275  memcpy(eav->actions, actions, s);
276  eav->num = numactions;
277  return &eav->h;
278}
279
280
281/**
282 *
283 */
284event_t *
285event_create_action(action_type_t action)
286{
287  return event_create_action_multi(&action, 1);
288}
289
290
291/**
292 *
293 */
294int
295event_is_action(event_t *e, action_type_t at)
296{
297  int i;
298  event_action_vector_t *eav;
299
300  if(e->e_type_x != EVENT_ACTION_VECTOR)
301    return 0;
302
303  eav = (event_action_vector_t *)e;
304
305  for(i = 0; i < eav->num; i++)
306    if(eav->actions[i] == at)
307      return 1;
308  return 0;
309}
310
311
312/**
313 *
314 */
315static void
316event_to_prop(prop_t *p, event_t *e)
317{
318  prop_send_ext_event(p, e);
319  prop_ref_dec(p);
320}
321
322
323/**
324 *
325 */
326void
327event_dispatch(event_t *e)
328{
329  prop_t *p;
330
331  if(event_is_action(e, ACTION_CLOSE) || event_is_action(e, ACTION_QUIT)) {
332    showtime_shutdown(0);
333
334  } else if(event_is_action(e, ACTION_SLEEP)) {
335    showtime_shutdown(10);
336
337  } else if(event_is_action(e, ACTION_NAV_BACK) ||
338            event_is_action(e, ACTION_NAV_FWD) ||
339            event_is_action(e, ACTION_HOME) ||
340            event_is_type(e, EVENT_OPENURL)) {
341    event_to_prop(prop_get_by_name(PNVEC("global", "nav", "eventsink"),
342                                   1, NULL), e);
343
344  } else if(event_is_action(e, ACTION_VOLUME_UP) ||
345            event_is_action(e, ACTION_VOLUME_DOWN)) {
346
347    p = prop_get_by_name(PNVEC("global", "audio", "mastervolume"), 1, NULL);
348    prop_add_float(p, event_is_action(e, ACTION_VOLUME_DOWN) ? -1 : 1);
349    prop_ref_dec(p);
350   
351  } else if(event_is_action(e, ACTION_VOLUME_MUTE_TOGGLE)) {
352
353    p = prop_get_by_name(PNVEC("global", "audio", "mastermute"), 1, NULL);
354    prop_toggle_int(p);
355    prop_ref_dec(p);
356
357  } else if(event_is_action(e, ACTION_SEEK_FAST_BACKWARD) ||
358            event_is_action(e, ACTION_SEEK_BACKWARD) ||
359            event_is_action(e, ACTION_SEEK_FAST_FORWARD) ||
360            event_is_action(e, ACTION_SEEK_FORWARD) ||
361            event_is_action(e, ACTION_PLAYPAUSE) ||
362            event_is_action(e, ACTION_PLAY) ||
363            event_is_action(e, ACTION_PAUSE) ||
364            event_is_action(e, ACTION_STOP) ||
365            event_is_action(e, ACTION_EJECT) ||
366            event_is_action(e, ACTION_PREV_TRACK) ||
367            event_is_action(e, ACTION_NEXT_TRACK) ||
368            event_is_action(e, ACTION_RESTART_TRACK) ||
369            event_is_action(e, ACTION_SHOW_MEDIA_STATS)
370            ) {
371
372    event_to_prop(prop_get_by_name(PNVEC("global", "media", "eventsink"),
373                                   1, NULL), e);
374  }
375
376
377  event_unref(e);
378}
379
Note: See TracBrowser for help on using the browser.