Skip to content

Latest commit

 

History

History
293 lines (232 loc) · 7.21 KB

gst-play-kb.c

File metadata and controls

293 lines (232 loc) · 7.21 KB
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/* GStreamer command line playback testing utility - keyboard handling helpers
*
* Copyright (C) 2013 Tim-Philipp Müller <tim centricular net>
* Copyright (C) 2013 Centricular Ltd
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gst-play-kb.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef G_OS_UNIX
#include <unistd.h>
#include <termios.h>
#endif
Sep 25, 2019
Sep 25, 2019
37
38
#ifdef G_OS_WIN32
#include <windows.h>
Oct 1, 2019
Oct 1, 2019
39
#include <io.h>
Sep 25, 2019
Sep 25, 2019
40
41
#endif
42
43
44
#include <gst/gst.h>
/* This is all not thread-safe, but doesn't have to be really */
Sep 25, 2019
Sep 25, 2019
45
46
static GstPlayKbFunc kb_callback;
static gpointer kb_callback_data;
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#ifdef G_OS_UNIX
static struct termios term_settings;
static gboolean term_settings_saved = FALSE;
static gulong io_watch_id;
static gboolean
gst_play_kb_io_cb (GIOChannel * ioc, GIOCondition cond, gpointer user_data)
{
GIOStatus status;
if (cond & G_IO_IN) {
gchar buf[16] = { 0, };
gsize read;
status = g_io_channel_read_chars (ioc, buf, sizeof (buf) - 1, &read, NULL);
if (status == G_IO_STATUS_ERROR)
return FALSE;
if (status == G_IO_STATUS_NORMAL) {
if (kb_callback)
kb_callback (buf, kb_callback_data);
}
}
return TRUE; /* call us again */
}
gboolean
gst_play_kb_set_key_handler (GstPlayKbFunc kb_func, gpointer user_data)
{
GIOChannel *ioc;
if (!isatty (STDIN_FILENO)) {
GST_INFO ("stdin is not connected to a terminal");
return FALSE;
}
if (io_watch_id > 0) {
g_source_remove (io_watch_id);
io_watch_id = 0;
}
if (kb_func == NULL && term_settings_saved) {
/* restore terminal settings */
if (tcsetattr (STDIN_FILENO, TCSAFLUSH, &term_settings) == 0)
term_settings_saved = FALSE;
else
g_warning ("could not restore terminal attributes");
setvbuf (stdin, NULL, _IOLBF, 0);
}
if (kb_func != NULL) {
struct termios new_settings;
if (!term_settings_saved) {
if (tcgetattr (STDIN_FILENO, &term_settings) != 0) {
g_warning ("could not save terminal attributes");
return FALSE;
}
term_settings_saved = TRUE;
/* Echo off, canonical mode off, extended input processing off */
new_settings = term_settings;
new_settings.c_lflag &= ~(ECHO | ICANON | IEXTEN);
Mar 26, 2018
Mar 26, 2018
112
113
new_settings.c_cc[VMIN] = 0;
new_settings.c_cc[VTIME] = 0;
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
if (tcsetattr (STDIN_FILENO, TCSAFLUSH, &new_settings) != 0) {
g_warning ("Could not set terminal state");
return FALSE;
}
setvbuf (stdin, NULL, _IONBF, 0);
}
}
ioc = g_io_channel_unix_new (STDIN_FILENO);
io_watch_id = g_io_add_watch_full (ioc, G_PRIORITY_DEFAULT, G_IO_IN,
(GIOFunc) gst_play_kb_io_cb, user_data, NULL);
g_io_channel_unref (ioc);
kb_callback = kb_func;
kb_callback_data = user_data;
return TRUE;
}
Sep 25, 2019
Sep 25, 2019
135
136
#elif defined(G_OS_WIN32)
Nov 19, 2019
Nov 19, 2019
137
138
139
140
141
142
143
144
145
146
typedef struct
{
GThread *thread;
HANDLE event_handle;
HANDLE console_handle;
gboolean closing;
GMutex lock;
} Win32KeyHandler;
static Win32KeyHandler *win32_handler = NULL;
Sep 25, 2019
Sep 25, 2019
147
148
static gboolean
Nov 19, 2019
Nov 19, 2019
149
gst_play_kb_source_cb (Win32KeyHandler * handler)
Sep 25, 2019
Sep 25, 2019
150
{
Nov 19, 2019
Nov 19, 2019
151
HANDLE h_input = handler->console_handle;
Sep 25, 2019
Sep 25, 2019
152
153
154
155
156
157
INPUT_RECORD buffer;
DWORD n;
if (PeekConsoleInput (h_input, &buffer, 1, &n) && n == 1) {
ReadConsoleInput (h_input, &buffer, 1, &n);
Nov 19, 2019
Nov 19, 2019
158
if (buffer.EventType == KEY_EVENT && buffer.Event.KeyEvent.bKeyDown) {
Sep 25, 2019
Sep 25, 2019
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
gchar key_val[2] = { 0 };
switch (buffer.Event.KeyEvent.wVirtualKeyCode) {
case VK_RIGHT:
kb_callback (GST_PLAY_KB_ARROW_RIGHT, kb_callback_data);
break;
case VK_LEFT:
kb_callback (GST_PLAY_KB_ARROW_LEFT, kb_callback_data);
break;
case VK_UP:
kb_callback (GST_PLAY_KB_ARROW_UP, kb_callback_data);
break;
case VK_DOWN:
kb_callback (GST_PLAY_KB_ARROW_DOWN, kb_callback_data);
break;
default:
key_val[0] = buffer.Event.KeyEvent.uChar.AsciiChar;
kb_callback (key_val, kb_callback_data);
break;
}
}
}
Nov 19, 2019
Nov 19, 2019
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
return G_SOURCE_REMOVE;
}
static gpointer
gst_play_kb_win32_thread (gpointer user_data)
{
Win32KeyHandler *handler = (Win32KeyHandler *) user_data;
HANDLE handles[2];
handles[0] = handler->event_handle;
handles[1] = handler->console_handle;
if (!kb_callback)
return NULL;
while (TRUE) {
DWORD ret = WaitForMultipleObjects (2, handles, FALSE, INFINITE);
if (ret == WAIT_FAILED) {
GST_WARNING ("WaitForMultipleObject Failed");
return NULL;
}
g_mutex_lock (&handler->lock);
if (handler->closing) {
g_mutex_unlock (&handler->lock);
return NULL;
}
g_mutex_unlock (&handler->lock);
g_idle_add ((GSourceFunc) gst_play_kb_source_cb, handler);
}
return NULL;
Sep 25, 2019
Sep 25, 2019
217
218
219
220
221
222
223
224
225
226
227
228
}
gboolean
gst_play_kb_set_key_handler (GstPlayKbFunc kb_func, gpointer user_data)
{
gint fd = _fileno (stdin);
if (!_isatty (fd)) {
GST_INFO ("stdin is not connected to a terminal");
return FALSE;
}
Nov 19, 2019
Nov 19, 2019
229
230
231
232
233
234
235
236
237
238
239
240
if (win32_handler) {
g_mutex_lock (&win32_handler->lock);
win32_handler->closing = TRUE;
g_mutex_unlock (&win32_handler->lock);
SetEvent (win32_handler->event_handle);
g_thread_join (win32_handler->thread);
CloseHandle (win32_handler->event_handle);
g_mutex_clear (&win32_handler->lock);
g_free (win32_handler);
win32_handler = NULL;
Sep 25, 2019
Sep 25, 2019
241
242
243
}
if (kb_func) {
Nov 19, 2019
Nov 19, 2019
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
SECURITY_ATTRIBUTES sec_attrs;
sec_attrs.nLength = sizeof (SECURITY_ATTRIBUTES);
sec_attrs.lpSecurityDescriptor = NULL;
sec_attrs.bInheritHandle = FALSE;
win32_handler = g_new0 (Win32KeyHandler, 1);
/* create cancellable event handle */
win32_handler->event_handle = CreateEvent (&sec_attrs, TRUE, FALSE, NULL);
if (!win32_handler->event_handle) {
GST_WARNING ("Couldn't create event handle");
g_free (win32_handler);
win32_handler = NULL;
return FALSE;
}
win32_handler->console_handle = GetStdHandle (STD_INPUT_HANDLE);
if (!win32_handler->console_handle) {
GST_WARNING ("Couldn't get console handle");
CloseHandle (win32_handler->event_handle);
g_free (win32_handler);
win32_handler = NULL;
return FALSE;
}
g_mutex_init (&win32_handler->lock);
win32_handler->thread =
g_thread_new ("gst-play-kb", gst_play_kb_win32_thread, win32_handler);
Sep 25, 2019
Sep 25, 2019
276
277
278
279
280
281
282
283
284
}
kb_callback = kb_func;
kb_callback_data = user_data;
return TRUE;
}
#else
285
286
287
288
289
gboolean
gst_play_kb_set_key_handler (GstPlayKbFunc key_func, gpointer user_data)
{
GST_FIXME ("Keyboard handling for this OS needs to be implemented");
Dec 9, 2013
Dec 9, 2013
290
return FALSE;
291
292
293
}
#endif /* !G_OS_UNIX */