[asterisk-commits] rizzo: trunk r97488 - /trunk/channels/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Jan 9 10:44:21 CST 2008


Author: rizzo
Date: Wed Jan  9 10:44:20 2008
New Revision: 97488

URL: http://svn.digium.com/view/asterisk?view=rev&rev=97488
Log:
Implement keyboard handling, and use it to enter
a number to dial in the 'message' area under the
keypad.

Now you can make calls using the keypad as a regular phone
(or the keyboard for chars not present on the keypad)


Modified:
    trunk/channels/console_board.c
    trunk/channels/console_gui.c
    trunk/channels/console_video.c
    trunk/channels/console_video.h

Modified: trunk/channels/console_board.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/console_board.c?view=diff&rev=97488&r1=97487&r2=97488
==============================================================================
--- trunk/channels/console_board.c (original)
+++ trunk/channels/console_board.c Wed Jan  9 10:44:20 2008
@@ -39,6 +39,7 @@
 
 #include "asterisk.h"	/* ast_strdupa */
 #include "asterisk/utils.h"	/* ast_strdupa */
+#include "console_video.h"	/* ast_strdupa */
 
 #ifdef HAVE_SDL	/* we only use this code if SDL is available */
 #include <SDL/SDL.h>
@@ -180,8 +181,8 @@
 	/* blit all characters */
 	for (i = first_char, col = 0; i <  last_char; i++) {
 		int c = b->text[i] - 32;	/* XXX first 32 chars are not printable */
-		if (c < 0)	/* should not happen, but just in case... */
-			continue;
+		if (c < 0) /* buffer terminator or anything else is a blank */
+			c = 0;
 		SDL_BlitSurface(b->font, &b->font_rects[c], b->screen, &dst);
 		/* point dst to next char position */
 		dst.x += dst.w;
@@ -195,11 +196,24 @@
 	SDL_UpdateRects(b->screen, 1, b->p_rect);	/* Update the screen */
 }
 
+/* return the content of a board */
+const char *read_message(const struct board *b)
+{
+	return b->text;
+}
+
+int reset_board(struct board *b)
+{
+	memset(b->text, ' ', b->v_w * b->v_h);	/* fill with spaces */
+	b->cur_col = 0;
+	b->cur_line = 0;
+	render_board(b);
+	return 0;
+}
 /* Store the message on the history board
  * and blit on screen if required.
  * XXX now easy. only regular chars
  */
-int print_message(struct board *b, const char *s);
 int print_message(struct board *b, const char *s)
 {
 	int i, l, row, col;
@@ -261,12 +275,14 @@
 			col = 0;
 			break;
 		case '\n':	/* move to beginning of next line */
+			dst[col] = '\0'; /* mark the rest of the line as empty */
 			col = 0;
 			dst += b->v_w;
 			break;
 		case '\b':	/* one char back */
 			if (col > 0)
 				col--;
+			dst[col] = ' '; /* delete current char */
 			break;
 		default:
 			if (s[i] < 32) /* signed, so take up to 127 */
@@ -280,6 +296,7 @@
 			break;
 		}
 	}
+	dst[col] = '\0'; /* the current position is empty */
 	b->cur_col = col;
 	/* everything is printed now, must do the rendering */
 	render_board(b);

Modified: trunk/channels/console_gui.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/console_gui.c?view=diff&rev=97488&r1=97487&r2=97488
==============================================================================
--- trunk/channels/console_gui.c (original)
+++ trunk/channels/console_gui.c Wed Jan  9 10:44:20 2008
@@ -80,6 +80,7 @@
 	KO_NONE,
 	KO_INPUT,	/* the local input window */
 	KO_DIALED,	/* the 'dialed number' window */
+	KO_MESSAGE,	/* the 'message' window */
 };
 
 enum drag_window {	/* which window are we dragging */
@@ -91,14 +92,8 @@
 	DRAG_MESSAGE,	/* message window */
 };
 
-struct board;	/* external. we only need the pointer */
-
 /*! \brief info related to the gui: button status, mouse coords, etc. */
 struct gui_info {
-	char			inbuf[GUI_BUFFER_LEN];	/* buffer for to-dial buffer */
-	int			inbuf_pos;	/* next free position in inbuf */
-	char			msgbuf[GUI_BUFFER_LEN];	/* buffer for text-message buffer */
-	int			msgbuf_pos;	/* next free position in msgbuf */
 	enum kb_output		kb_output;	/* where the keyboard output goes */
 	enum drag_window	drag_window;	/* which window are we dragging */
 	int			x_drag;		/* x coordinate where the drag starts */
@@ -238,11 +233,12 @@
 	KEY_SENDVIDEO = 132,
 	KEY_LOCALVIDEO = 133,
 	KEY_REMOTEVIDEO = 134,
-	KEY_WRITEMESSAGE = 135,
 	KEY_FLASH = 136,
 	KEY_GUI_CLOSE = 199,		/* close gui */
 
-	/* regions of the skin - active area, fonts, etc. */
+	/* regions of the skin - displayed area, fonts, etc.
+	 * XXX NOTE these are not sensitive areas.
+	 */
 	KEY_KEYPAD = 200,		/* the keypad - default to the whole image */
 	KEY_FONT = 201,		/* the font. Maybe not really useful */
 	KEY_MESSAGE = 202,	/* area for incoming messages */
@@ -262,27 +258,6 @@
  * Handlers for the various keypad functions
  */
 
-/*! \brief append a character, or reset if  c = '\0' */
-static void append_char(char *str, int *str_pos, const char c)
-{
-	int i = *str_pos;
-	if (c == '\0')
-		i = 0;
-	else if (i < GUI_BUFFER_LEN - 1)
-		str[i++] = c;
-	else
-		i = GUI_BUFFER_LEN - 1; /* unnecessary, i think */
-	str = '\0';
-	*str_pos = i;
-}
-
-/*! \brief append string to a buffer */
-static void append_string(char *str, int *str_pos, const char *s)
-{
-	while (*s)
-		append_char(str, str_pos, *s++);
-}
-
 /* accumulate digits, possibly call dial if in connected mode */
 static void keypad_digit(struct video_desc *env, int digit)
 {	
@@ -292,7 +267,9 @@
 		f.subclass = digit;
 		ast_queue_frame(env->owner, &f);
 	} else {		/* no call, accumulate digits */
-		append_char(env->gui->inbuf, &env->gui->inbuf_pos, digit);
+		char buf[2] = { digit, '\0' };
+		if (env->gui->bd_msg) /* XXX not strictly necessary ... */
+			print_message(env->gui->bd_msg, buf);
 	}
 }
 
@@ -340,11 +317,15 @@
 
 	if (env->owner) { /* someone is calling us, just answer */
 		ast_cli_command(gui->outfd, "console answer");
-	} else if (gui->inbuf_pos) { /* we have someone to call */
-		ast_cli_command(gui->outfd, gui->inbuf);
-	}
-	append_char(gui->inbuf, &gui->inbuf_pos, '\0'); /* clear buffer */
-	append_string(gui->inbuf, &gui->inbuf_pos, "console dial ");
+	} else { /* we have someone to call */
+		char buf[160];
+		buf[sizeof(buf) - 1] = '\0';
+		snprintf(buf, sizeof(buf) - 1, "console dial %s",
+			ast_skip_blanks(read_message(gui->bd_msg)));
+		ast_log(LOG_WARNING, "doing <%s>\n", buf);
+		reset_board(gui->bd_msg);
+		ast_cli_command(gui->outfd, buf);
+	}
 }
 
 #if 0 /* still unused */
@@ -474,30 +455,68 @@
  * depending on the text_mode variable value.
  *
  * key is the SDLKey structure corresponding to the key pressed.
- * XXX needs to be cleaned up when handling returns etc.
- */
-static void handle_keyboard_input(struct video_desc *env, SDLKey key)
-{
+ * Note that SDL returns modifiers (ctrl, shift, alt) as independent
+ * information so the key itself is not enough and we need to
+ * use a translation table, below - one line per entry,
+ * plain, shift, ctrl, ... using the first char as key.
+ */
+static const char *us_kbd_map[] = {
+	"`~", "1!", "2@", "3#", "4$", "5%", "6^",
+	"7&", "8*", "9(", "0)", "-_", "=+", "[{",
+	"]}", "\\|", ";:", "'\"", ",<", ".>", "/?",
+	"jJ\n",
+	NULL
+};
+
+static const char map_key(SDL_keysym *ks)
+{
+	const char *s, **p = us_kbd_map;
+	int c = ks->sym;
+
+	if (c == '\r')	/* map cr into lf */
+		c = '\n';
+	if (c >= SDLK_NUMLOCK && c <= SDLK_COMPOSE)
+		return 0;	/* only a modifier */
+	if (ks->mod == 0)
+		return c;
+	while ((s = *p) && s[0] != c)
+		p++;
+	if (s) { /* see if we have a modifier and a chance to use it */
+		int l = strlen(s), mod = 0;
+		if (l > 1)
+			mod |= (ks->mod & KMOD_SHIFT) ? 1 : 0;
+		if (l > 2 + mod)
+			mod |= (ks->mod & KMOD_CTRL) ? 2 : 0;
+		if (l > 4 + mod)
+			mod |= (ks->mod & KMOD_ALT) ? 4 : 0;
+		c = s[mod];
+	}
+	if (ks->mod & (KMOD_CAPS|KMOD_SHIFT) && c >= 'a' && c <='z')
+		c += 'A' - 'a';
+	return c;
+}
+
+static void handle_keyboard_input(struct video_desc *env, SDL_keysym *ks)
+{
+	char buf[2] = { map_key(ks), '\0' };
 	struct gui_info *gui = env->gui;
+	if (buf[0] == 0)	/* modifier ? */
+		return;
 	switch (gui->kb_output) {
 	default:
 		break;
-	case KO_INPUT:
-		/* append in the text-message buffer */
-		if (key == SDLK_RETURN) {
-			/* send the text message and return in normal mode */
-			gui->kb_output = KO_NONE;
-			ast_cli_command(gui->outfd, gui->msgbuf);
-			append_char(gui->msgbuf, &gui->msgbuf_pos, '\0');
-		} else {
-			/* accumulate the key in the message buffer */
-			append_char(gui->msgbuf, &gui->msgbuf_pos, key);
-		}
-		break;
-	case KO_DIALED:
-		/* XXX actually, enter should be a 'console dial ' */
-		/* append in the dial buffer */
-		append_char(gui->inbuf, &gui->inbuf_pos, key);
+	case KO_INPUT:	/* to be completed */
+		break;
+	case KO_MESSAGE:
+		if (gui->bd_msg) {
+			print_message(gui->bd_msg, buf);
+			if (buf[0] == '\r' || buf[0] == '\n') {
+				keypad_pick_up(env);
+			}
+		}
+		break;
+
+	case KO_DIALED: /* to be completed */
 		break;
 	}
 
@@ -564,7 +583,7 @@
 #endif
 			switch (ev[i].type) {
 			case SDL_KEYDOWN:
-				handle_keyboard_input(env, ev[i].key.keysym.sym);
+				handle_keyboard_input(env, &ev[i].key.keysym);
 				break;
 			case SDL_MOUSEMOTION:
 				if (gui->drag_window == DRAG_LOCAL)
@@ -626,14 +645,9 @@
 	if (gui == NULL)
 		return NULL;
 	/* initialize keypad status */
-	gui->kb_output = KO_DIALED;
+	gui->kb_output = KO_MESSAGE;	/* XXX temp */
 	gui->drag_window = DRAG_NONE;
 	gui->outfd = -1;
-
-	/* initialize keyboard buffer */
-	append_char(gui->inbuf, &gui->inbuf_pos, '\0');
-	append_string(gui->inbuf, &gui->inbuf_pos, "console dial ");
-	append_char(gui->msgbuf, &gui->msgbuf_pos, '\0');
 
 	keypad_setup(gui, keypad_file);
 	if (gui->keypad == NULL)	/* no keypad, we are done */
@@ -896,7 +910,6 @@
         {"SENDVIDEO",	KEY_SENDVIDEO },
         {"LOCALVIDEO",	KEY_LOCALVIDEO },
         {"REMOTEVIDEO",	KEY_REMOTEVIDEO },
-        {"WRITEMESSAGE", KEY_WRITEMESSAGE },
         {"GUI_CLOSE",	KEY_GUI_CLOSE },
         {"KEYPAD",	KEY_KEYPAD },	/* x0 y0 w h - active area of the keypad */
         {"MESSAGE",	KEY_MESSAGE },	/* x0 y0 w h - incoming messages */

Modified: trunk/channels/console_video.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/console_video.c?view=diff&rev=97488&r1=97487&r2=97488
==============================================================================
--- trunk/channels/console_video.c (original)
+++ trunk/channels/console_video.c Wed Jan  9 10:44:20 2008
@@ -667,8 +667,6 @@
 	return v->enc->enc_encap(&v->enc_out, v->mtu, tail);
 }
 
-int print_message(struct board *b, const char *s);
-
 /*
  * Helper thread to periodically poll the video source and enqueue the
  * generated frames to the channel's queue.
@@ -724,10 +722,6 @@
 		struct ast_channel *chan;
 		int fd;
 		char *caption = NULL, buf[160];
-
-		sprintf(buf, "%d   \r", count);
-		if (env->gui)
-			print_message(env->gui->bd_msg, buf);
 
 		/* determine if video format changed */
 		if (count++ % 10 == 0) {

Modified: trunk/channels/console_video.h
URL: http://svn.digium.com/view/asterisk/trunk/channels/console_video.h?view=diff&rev=97488&r1=97487&r2=97488
==============================================================================
--- trunk/channels/console_video.h (original)
+++ trunk/channels/console_video.h Wed Jan  9 10:44:20 2008
@@ -86,5 +86,16 @@
 void console_video_uninit(struct video_desc *env);
 void console_video_start(struct video_desc *env, struct ast_channel *owner);
 
+/* console_board.c */
+struct board;
+/* !\brief print a message on a board */
+int print_message(struct board *b, const char *s);
+
+/*! \brief return the whole text from a board */
+const char *read_message(const struct board *b);
+
+/*! \brief reset the board to blank */
+int reset_board(struct board *b);
+
 #endif /* CONSOLE_VIDEO_H */
 /* end of file */




More information about the asterisk-commits mailing list