summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorphintuka <phintuka>2011-01-23 19:42:08 +0000
committerphintuka <phintuka>2011-01-23 19:42:08 +0000
commit7f9ae5ee0222e54abb2c7a98cedaed927f563f91 (patch)
tree8bfde405b01b819eb58aedad091a80a7f91a8d6c
parentb20599cb1602fdd10d769f8d047e70469ec14293 (diff)
downloadxineliboutput-7f9ae5ee0222e54abb2c7a98cedaed927f563f91.tar.gz
xineliboutput-7f9ae5ee0222e54abb2c7a98cedaed927f563f91.tar.bz2
Moved keyboard handling to xine_frontend_kbd.c
-rw-r--r--Makefile4
-rw-r--r--xine_frontend_kbd.c328
-rw-r--r--xine_frontend_kbd.h19
-rw-r--r--xine_frontend_main.c296
4 files changed, 351 insertions, 296 deletions
diff --git a/Makefile b/Makefile
index 9e0a3f73..be6e6b5c 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@
# See the main source file 'xineliboutput.c' for copyright information and
# how to reach the author.
#
-# $Id: Makefile,v 1.105 2010-12-15 14:43:36 phintuka Exp $
+# $Id: Makefile,v 1.106 2011-01-23 19:42:08 phintuka Exp $
#
# The official name of this plugin.
@@ -219,7 +219,7 @@ OBJS_MPG = black_720x576.o nosignal_720x576.o vdrlogo_720x576.o
OBJS_FE_SO = xine_frontend.o logdefs.o \
xine/post.o xine/vo_hook.o xine/vo_osdscaler.o xine/vo_osdreorder.o xine/vo_lastpts.o \
tools/rle.o
-OBJS_FE = $(OBJS_FE_SO) tools/vdrdiscovery.o xine_frontend_main.o xine_frontend_lirc.o
+OBJS_FE = $(OBJS_FE_SO) tools/vdrdiscovery.o xine_frontend_main.o xine_frontend_lirc.o xine_frontend_kbd.o
OBJS_SXFE_SO = xine_sxfe_frontend.o $(OBJS_FE_SO)
OBJS_SXFE = xine_sxfe_frontend.o $(OBJS_FE)
diff --git a/xine_frontend_kbd.c b/xine_frontend_kbd.c
new file mode 100644
index 00000000..c750d08f
--- /dev/null
+++ b/xine_frontend_kbd.c
@@ -0,0 +1,328 @@
+/*
+ * xine_frontend_kbd.c: Forward (local) console key presses to VDR (server)
+ *
+ * See the main source file 'xineliboutput.c' for copyright information and
+ * how to reach the author.
+ *
+ * $Id: xine_frontend_kbd.c,v 1.1 2011-01-23 19:42:08 phintuka Exp $
+ *
+ */
+
+#include "features.h"
+
+#include <inttypes.h>
+#include <poll.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+
+
+#define LOG_MODULENAME "[console] "
+#include "logdefs.h"
+
+#include "xine_frontend.h"
+#include "xine_frontend_kbd.h"
+
+/*
+ * stdin (keyboard/slave mode) reading
+ */
+
+/* static data */
+static pthread_t kbd_thread;
+static struct termios tm, saved_tm;
+
+/* xine_frontend_main.c: */
+extern int gui_hotkeys;
+
+
+/*
+ * read_key()
+ *
+ * Try to read single char from stdin.
+ *
+ * Returns: >=0 char readed
+ * -1 nothing to read
+ * -2 fatal error
+ */
+#define READ_KEY_ERROR -2
+#define READ_KEY_EAGAIN -1
+static int read_key(void)
+{
+ unsigned char ch;
+ int err;
+ struct pollfd pfd;
+ pfd.fd = STDIN_FILENO;
+ pfd.events = POLLIN;
+
+ errno = 0;
+ pthread_testcancel();
+
+ if (1 == (err = poll(&pfd, 1, 50))) {
+ pthread_testcancel();
+
+ if (1 == (err = read(STDIN_FILENO, &ch, 1)))
+ return (int)ch;
+
+ if (err < 0)
+ LOGERR("read_key: read(stdin) failed");
+ else
+ LOGERR("read_key: read(stdin) failed: no stdin");
+ return READ_KEY_ERROR;
+
+ } else if (err < 0 && errno != EINTR) {
+ LOGERR("read_key: poll(stdin) failed");
+ return READ_KEY_ERROR;
+ }
+
+ pthread_testcancel();
+
+ return READ_KEY_EAGAIN;
+}
+
+/*
+ * read_key_seq()
+ *
+ * Read a key sequence from stdin.
+ * Key sequence is either normal key or escape sequence.
+ *
+ * Returns the key or escape sequence as uint64_t.
+ *
+ * Originally copied from vdr:
+ * remote.c: General Remote Control handling
+ * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
+ */
+#define READ_KEY_SEQ_ERROR 0xffffffff
+static uint64_t read_key_seq(void)
+{
+ /* from vdr, remote.c */
+ uint64_t k = 0;
+ int key1;
+
+ if ((key1 = read_key()) >= 0) {
+ k = key1;
+ if (key1 == 0x1B) {
+ /* Start of escape sequence */
+ if ((key1 = read_key()) >= 0) {
+ k <<= 8;
+ k |= key1 & 0xFF;
+ switch (key1) {
+ case 0x4F: /* 3-byte sequence */
+ if ((key1 = read_key()) >= 0) {
+ k <<= 8;
+ k |= key1 & 0xFF;
+ }
+ break;
+ case 0x5B: /* 3- or more-byte sequence */
+ if ((key1 = read_key()) >= 0) {
+ k <<= 8;
+ k |= key1 & 0xFF;
+ switch (key1) {
+ case 0x31 ... 0x3F: /* more-byte sequence */
+ case 0x5B: /* strange, may apparently occur */
+ do {
+ if ((key1 = read_key()) < 0)
+ break; /* Sequence ends here */
+ k <<= 8;
+ k |= key1 & 0xFF;
+ } while (key1 != 0x7E);
+ break;
+ default:;
+ }
+ }
+ break;
+ default:;
+ }
+ }
+ }
+ }
+
+ if (key1 == READ_KEY_ERROR)
+ return READ_KEY_SEQ_ERROR;
+
+ return k;
+}
+
+/*
+ * kbd_receiver_thread()
+ *
+ * Read key(sequence)s from stdin and pass those to frontend.
+ */
+
+static void kbd_receiver_thread_cleanup(void *arg)
+{
+ int status;
+ tcsetattr(STDIN_FILENO, TCSANOW, &saved_tm);
+ status = system("setterm -cursor on");
+ LOGMSG("Keyboard thread terminated");
+}
+
+static void *kbd_receiver_thread(void *fe_gen)
+{
+ frontend_t *fe = (frontend_t*)fe_gen;
+ uint64_t code = 0;
+ char str[64];
+ int status;
+
+ status = system("setterm -cursor off");
+ status = system("setterm -blank off");
+
+ /* Set stdin to deliver keypresses without buffering whole lines */
+ tcgetattr(STDIN_FILENO, &saved_tm);
+ if (tcgetattr(STDIN_FILENO, &tm) == 0) {
+ tm.c_iflag = 0;
+ tm.c_lflag &= ~(ICANON | ECHO);
+ tm.c_cc[VMIN] = 0;
+ tm.c_cc[VTIME] = 0;
+ tcsetattr(STDIN_FILENO, TCSANOW, &tm);
+ }
+
+ pthread_cleanup_push(kbd_receiver_thread_cleanup, NULL);
+
+ do {
+ alarm(0);
+ errno = 0;
+ code = read_key_seq();
+ alarm(3); /* watchdog */
+ if (code == 0)
+ continue;
+ if (code == READ_KEY_SEQ_ERROR)
+ break;
+ if (code == 27) {
+ fe->send_event(fe, "QUIT");
+ break;
+ }
+
+ if (gui_hotkeys) {
+ if (code == 'f' || code == 'F') {
+ fe->send_event(fe, "TOGGLE_FULLSCREEN");
+ continue;
+ }
+ if (code == 'p' || code == 'P') {
+ fe->send_event(fe, "POWER_OFF");
+ continue;
+ }
+ if (code == 'd' || code == 'D') {
+ fe->send_event(fe, "TOGGLE_DEINTERLACE");
+ continue;
+ }
+ }
+
+ snprintf(str, sizeof(str), "%016" PRIX64, code);
+ fe->send_input_event(fe, "KBD", str, 0, 0);
+
+ } while (fe->xine_is_finished(fe, 0) != FE_XINE_EXIT);
+
+ alarm(0);
+
+ LOGDBG("Keyboard thread terminating");
+
+ pthread_cleanup_pop(1);
+
+ pthread_exit(NULL);
+ return NULL; /* never reached */
+}
+
+/*
+ * slave_receiver_thread()
+ *
+ * Read slave mode commands from stdin
+ * Interpret and execute valid commands
+ */
+
+static void slave_receiver_thread_cleanup(void *arg)
+{
+ /* restore terminal settings */
+ tcsetattr(STDIN_FILENO, TCSANOW, &saved_tm);
+ LOGDBG("Slave mode receiver terminated");
+}
+
+static void *slave_receiver_thread(void *fe_gen)
+{
+ frontend_t *fe = (frontend_t*)fe_gen;
+ char str[128], *pt;
+
+ tcgetattr(STDIN_FILENO, &saved_tm);
+
+ pthread_cleanup_push(slave_receiver_thread_cleanup, NULL);
+
+ do {
+ errno = 0;
+ str[0] = 0;
+
+ pthread_testcancel();
+ if (!fgets(str, sizeof(str), stdin))
+ break;
+ pthread_testcancel();
+
+ if (NULL != (pt = strchr(str, '\r')))
+ *pt = 0;
+ if (NULL != (pt = strchr(str, '\n')))
+ *pt = 0;
+
+ if (!strncasecmp(str, "QUIT", 4)) {
+ fe->send_event(fe, "QUIT");
+ break;
+ }
+ if (!strncasecmp(str, "FULLSCREEN", 10)) {
+ if (strpbrk(str + 10, "01"))
+ fe->send_event(fe, str);
+ else
+ fe->send_event(fe, "TOGGLE_FULLSCREEN");
+ continue;
+ }
+ if (!strncasecmp(str, "DEINTERLACE ", 12)) {
+ fe->send_event(fe, str);
+ continue;
+ }
+ if (!strncasecmp(str, "HITK ", 5)) {
+ fe->send_input_event(fe, NULL, str+5, 0, 0);
+ continue;
+ }
+
+ LOGMSG("Unknown slave mode command: %s", str);
+
+ } while (fe->xine_is_finished(fe, 0) != FE_XINE_EXIT);
+
+ LOGDBG("Slave mode receiver terminating");
+
+ pthread_cleanup_pop(1);
+
+ pthread_exit(NULL);
+ return NULL; /* never reached */
+}
+
+/*
+ * kbd_start()
+ *
+ * Start keyboard/slave mode reader thread
+ */
+void kbd_start(frontend_t *fe, int slave_mode)
+{
+ int err;
+ if ((err = pthread_create (&kbd_thread,
+ NULL,
+ slave_mode ? slave_receiver_thread : kbd_receiver_thread,
+ (void*)fe)) != 0) {
+ fprintf(stderr, "Can't create new thread for keyboard (%s)\n",
+ strerror(err));
+ }
+}
+
+/*
+ * kbd_stop()
+ *
+ * Stop keyboard/slave mode reader thread
+ */
+void kbd_stop(void)
+{
+ void *p;
+
+ pthread_cancel(kbd_thread);
+ pthread_join(kbd_thread, &p);
+}
+
+
diff --git a/xine_frontend_kbd.h b/xine_frontend_kbd.h
new file mode 100644
index 00000000..af22ad42
--- /dev/null
+++ b/xine_frontend_kbd.h
@@ -0,0 +1,19 @@
+/*
+ * xine_frontend_kbd.h:
+ *
+ * See the main source file 'xineliboutput.c' for copyright information and
+ * how to reach the author.
+ *
+ * $Id: xine_frontend_kbd.h,v 1.1 2011-01-23 19:42:08 phintuka Exp $
+ *
+ */
+
+#ifndef XINE_FRONTEND_KBD_H
+#define XINE_FRONTEND_KBD_H
+
+struct frontend_s;
+
+void kbd_start(frontend_t *fe, int slave_mode);
+void kbd_stop(void);
+
+#endif /* XINE_FRONTEND_KBD_H */
diff --git a/xine_frontend_main.c b/xine_frontend_main.c
index 6d1dede7..48cc0e38 100644
--- a/xine_frontend_main.c
+++ b/xine_frontend_main.c
@@ -4,7 +4,7 @@
* See the main source file 'xineliboutput.c' for copyright information and
* how to reach the author.
*
- * $Id: xine_frontend_main.c,v 1.93 2011-01-17 12:54:22 phintuka Exp $
+ * $Id: xine_frontend_main.c,v 1.94 2011-01-23 19:42:08 phintuka Exp $
*
*/
@@ -14,10 +14,6 @@
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
-#include <poll.h>
-#include <errno.h>
-#include <termios.h>
-#include <pthread.h>
#include <unistd.h>
#include <syslog.h>
#include <getopt.h>
@@ -32,6 +28,7 @@
#include "xine_frontend.h"
#include "tools/vdrdiscovery.h"
#include "xine_frontend_lirc.h"
+#include "xine_frontend_kbd.h"
/* static data */
@@ -42,295 +39,6 @@ volatile int last_signal = 0;
int gui_hotkeys = 0;
/*
- * stdin (keyboard/slave mode) reading
- */
-
-/* static data */
-pthread_t kbd_thread;
-struct termios tm, saved_tm;
-
-/*
- * read_key()
- *
- * Try to read single char from stdin.
- *
- * Returns: >=0 char readed
- * -1 nothing to read
- * -2 fatal error
- */
-#define READ_KEY_ERROR -2
-#define READ_KEY_EAGAIN -1
-static int read_key(void)
-{
- unsigned char ch;
- int err;
- struct pollfd pfd;
- pfd.fd = STDIN_FILENO;
- pfd.events = POLLIN;
-
- errno = 0;
- pthread_testcancel();
-
- if (1 == (err = poll(&pfd, 1, 50))) {
- pthread_testcancel();
-
- if (1 == (err = read(STDIN_FILENO, &ch, 1)))
- return (int)ch;
-
- if (err < 0)
- LOGERR("read_key: read(stdin) failed");
- else
- LOGERR("read_key: read(stdin) failed: no stdin");
- return READ_KEY_ERROR;
-
- } else if (err < 0 && errno != EINTR) {
- LOGERR("read_key: poll(stdin) failed");
- return READ_KEY_ERROR;
- }
-
- pthread_testcancel();
- return READ_KEY_EAGAIN;
-}
-
-/*
- * read_key_seq()
- *
- * Read a key sequence from stdin.
- * Key sequence is either normal key or escape sequence.
- *
- * Returns the key or escape sequence as uint64_t.
- */
-#define READ_KEY_SEQ_ERROR 0xffffffff
-static uint64_t read_key_seq(void)
-{
- /* from vdr, remote.c */
- uint64_t k = 0;
- int key1;
-
- if ((key1 = read_key()) >= 0) {
- k = key1;
- if (key1 == 0x1B) {
- /* Start of escape sequence */
- if ((key1 = read_key()) >= 0) {
- k <<= 8;
- k |= key1 & 0xFF;
- switch (key1) {
- case 0x4F: /* 3-byte sequence */
- if ((key1 = read_key()) >= 0) {
- k <<= 8;
- k |= key1 & 0xFF;
- }
- break;
- case 0x5B: /* 3- or more-byte sequence */
- if ((key1 = read_key()) >= 0) {
- k <<= 8;
- k |= key1 & 0xFF;
- switch (key1) {
- case 0x31 ... 0x3F: /* more-byte sequence */
- case 0x5B: /* strange, may apparently occur */
- do {
- if ((key1 = read_key()) < 0)
- break; /* Sequence ends here */
- k <<= 8;
- k |= key1 & 0xFF;
- } while (key1 != 0x7E);
- break;
- default:;
- }
- }
- break;
- default:;
- }
- }
- }
- }
-
- if (key1 == READ_KEY_ERROR)
- return READ_KEY_SEQ_ERROR;
-
- return k;
-}
-
-/*
- * kbd_receiver_thread()
- *
- * Read key(sequence)s from stdin and pass those to frontend.
- */
-
-static void kbd_receiver_thread_cleanup(void *arg)
-{
- int status;
- tcsetattr(STDIN_FILENO, TCSANOW, &saved_tm);
- status = system("setterm -cursor on");
- LOGMSG("Keyboard thread terminated");
-}
-
-static void *kbd_receiver_thread(void *fe_gen)
-{
- frontend_t *fe = (frontend_t*)fe_gen;
- uint64_t code = 0;
- char str[64];
- int status;
-
- status = system("setterm -cursor off");
- status = system("setterm -blank off");
-
- /* Set stdin to deliver keypresses without buffering whole lines */
- tcgetattr(STDIN_FILENO, &saved_tm);
- if (tcgetattr(STDIN_FILENO, &tm) == 0) {
- tm.c_iflag = 0;
- tm.c_lflag &= ~(ICANON | ECHO);
- tm.c_cc[VMIN] = 0;
- tm.c_cc[VTIME] = 0;
- tcsetattr(STDIN_FILENO, TCSANOW, &tm);
- }
-
- pthread_cleanup_push(kbd_receiver_thread_cleanup, NULL);
-
- do {
- alarm(0);
- errno = 0;
- code = read_key_seq();
- alarm(3); /* watchdog */
- if (code == 0)
- continue;
- if (code == READ_KEY_SEQ_ERROR)
- break;
- if (code == 27) {
- fe->send_event(fe, "QUIT");
- break;
- }
-
- if (gui_hotkeys) {
- if (code == 'f' || code == 'F') {
- fe->send_event(fe, "TOGGLE_FULLSCREEN");
- continue;
- }
- if (code == 'p' || code == 'P') {
- fe->send_event(fe, "POWER_OFF");
- continue;
- }
- if (code == 'd' || code == 'D') {
- fe->send_event(fe, "TOGGLE_DEINTERLACE");
- continue;
- }
- }
-
- snprintf(str, sizeof(str), "%016" PRIX64, code);
- fe->send_input_event(fe, "KBD", str, 0, 0);
-
- } while (fe->xine_is_finished(fe, 0) != FE_XINE_EXIT);
-
- alarm(0);
-
- LOGDBG("Keyboard thread terminating");
-
- pthread_cleanup_pop(1);
-
- pthread_exit(NULL);
- return NULL; /* never reached */
-}
-
-/*
- * slave_receiver_thread()
- *
- * Read slave mode commands from stdin
- * Interpret and execute valid commands
- */
-
-static void slave_receiver_thread_cleanup(void *arg)
-{
- /* restore terminal settings */
- tcsetattr(STDIN_FILENO, TCSANOW, &saved_tm);
- LOGDBG("Slave mode receiver terminated");
-}
-
-static void *slave_receiver_thread(void *fe_gen)
-{
- frontend_t *fe = (frontend_t*)fe_gen;
- char str[128], *pt;
-
- tcgetattr(STDIN_FILENO, &saved_tm);
-
- pthread_cleanup_push(slave_receiver_thread_cleanup, NULL);
-
- do {
- errno = 0;
- str[0] = 0;
-
- pthread_testcancel();
- if (!fgets(str, sizeof(str), stdin))
- break;
- pthread_testcancel();
-
- if (NULL != (pt = strchr(str, '\r')))
- *pt = 0;
- if (NULL != (pt = strchr(str, '\n')))
- *pt = 0;
-
- if (!strncasecmp(str, "QUIT", 4)) {
- fe->send_event(fe, "QUIT");
- break;
- }
- if (!strncasecmp(str, "FULLSCREEN", 10)) {
- if (strpbrk(str + 10, "01"))
- fe->send_event(fe, str);
- else
- fe->send_event(fe, "TOGGLE_FULLSCREEN");
- continue;
- }
- if (!strncasecmp(str, "DEINTERLACE ", 12)) {
- fe->send_event(fe, str);
- continue;
- }
- if (!strncasecmp(str, "HITK ", 5)) {
- fe->send_input_event(fe, NULL, str+5, 0, 0);
- continue;
- }
-
- LOGMSG("Unknown slave mode command: %s", str);
-
- } while (fe->xine_is_finished(fe, 0) != FE_XINE_EXIT);
-
- LOGDBG("Slave mode receiver terminating");
-
- pthread_cleanup_pop(1);
-
- pthread_exit(NULL);
- return NULL; /* never reached */
-}
-
-/*
- * kbd_start()
- *
- * Start keyboard/slave mode reader thread
- */
-static void kbd_start(frontend_t *fe, int slave_mode)
-{
- int err;
- if ((err = pthread_create (&kbd_thread,
- NULL,
- slave_mode ? slave_receiver_thread : kbd_receiver_thread,
- (void*)fe)) != 0) {
- fprintf(stderr, "Can't create new thread for keyboard (%s)\n",
- strerror(err));
- }
-}
-
-/*
- * kbd_stop()
- *
- * Stop keyboard/slave mode reader thread
- */
-static void kbd_stop(void)
-{
- void *p;
-
- pthread_cancel(kbd_thread);
- pthread_join(kbd_thread, &p);
-}
-
-/*
* SignalHandler()
*/
static void SignalHandler(int signum)