[asterisk-commits] marta: branch group/video_console r90428 - /team/group/video_console/channels/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Sat Dec 1 09:12:33 CST 2007
Author: marta
Date: Sat Dec 1 09:12:32 2007
New Revision: 90428
URL: http://svn.digium.com/view/asterisk?view=rev&rev=90428
Log:
Added event handler for write message.
Added drag of the X11 capture source.
Modified:
team/group/video_console/channels/console_video.c
Modified: team/group/video_console/channels/console_video.c
URL: http://svn.digium.com/view/asterisk/team/group/video_console/channels/console_video.c?view=diff&rev=90428&r1=90427&r2=90428
==============================================================================
--- team/group/video_console/channels/console_video.c (original)
+++ team/group/video_console/channels/console_video.c Sat Dec 1 09:12:32 2007
@@ -115,7 +115,9 @@
int size; /* total size in bytes */
int used; /* space used so far */
int ebit; /* bits to ignore at the end */
- int w;
+ int x; /* origin, if necessary */
+ int y;
+ int w; /* size */
int h;
int pix_fmt;
};
@@ -165,6 +167,8 @@
#ifdef HAVE_X11
Display *dpy; /* x11 grabber info */
XImage *image;
+ int X_max_width; /* max width of X screen */
+ int X_max_height; /* max height of X screen */
#endif
};
@@ -246,10 +250,18 @@
SDL_Rect rect; /* loc. of images */
};
+#define GUI_BUFFER_LEN 256 /* buffer lenght used for input buffers */
+
/*! \brief info related to the gui: button status, mouse coords, etc. */
struct gui_info {
- char inbuf[256]; /* buffer for keypad input */
+ 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 */
+ int text_mode; /* switch to-dial and text-message mode */
+ int drag_mode; /* switch phone and drag-source mode */
+ int x_drag; /* x coordinate where the drag starts */
+ int y_drag; /* y coordinate where the drag starts */
#ifdef HAVE_SDL_TTF
TTF_Font *font; /* font to be used */
#endif
@@ -1340,18 +1352,24 @@
* if the device is "X11", then open the x11 grabber
*/
if (!strcasecmp(v->videodevice, "X11")) {
- int x_ofs = 0;
- int y_ofs = 0;
XImage *im;
-
+ int screen_num;
+
+ /* init the connection with the X server */
v->dpy = XOpenDisplay(NULL);
if (v->dpy == NULL) {
ast_log(LOG_WARNING, "error opening display\n");
goto error;
}
+
+ /* find width and height of the screen */
+ screen_num = DefaultScreen(v->dpy);
+ v->X_max_width = DisplayWidth(v->dpy, screen_num);
+ v->X_max_height = DisplayHeight(v->dpy, screen_num);
+
v->image = im = XGetImage(v->dpy,
RootWindow(v->dpy, DefaultScreen(v->dpy)),
- x_ofs, y_ofs, b->w, b->h, AllPlanes, ZPixmap);
+ b->x, b->y, b->w, b->h, AllPlanes, ZPixmap);
if (v->image == NULL) {
ast_log(LOG_WARNING, "error creating Ximage\n");
goto error;
@@ -1441,6 +1459,9 @@
goto error;
}
ast_log(LOG_WARNING, "success opening camera\n");
+
+ /* XXX don't know if this is really needed */
+ v->X_max_width = v->X_max_height = 0;
}
#endif /* HAVE_VIDEODEV_H */
@@ -1486,7 +1507,7 @@
AVPicture p;
XGetSubImage(v->dpy,
RootWindow(v->dpy, DefaultScreen(v->dpy)),
- 0, 0, b->w, b->h, AllPlanes, ZPixmap, v->image, 0, 0);
+ b->x, b->y, b->w, b->h, AllPlanes, ZPixmap, v->image, 0, 0);
b->data = (uint8_t *)v->image->data;
fill_pict(b, &p);
@@ -2152,6 +2173,11 @@
- keystrokes are used as keypad functions, or as text input
if we are in text-input mode.
+To manage these behavior we use two status variables,
+that defines if keyboard events should be redirect to dialing functions
+or to write message functions, and if mouse events should be used
+to implement keypad functionalities or to drag the capture device.
+
Configuration options control the appeareance of the gui:
keypad = /tmp/phone.jpg ; the keypad on the screen
@@ -2190,17 +2216,17 @@
*/
/*! \brief append a character, or reset if '\0' */
-static void append_char(struct video_desc *env, const char c)
-{
- int i = env->gui.inbuf_pos;
+static void append_char(char *str, int *str_pos, const char c)
+{
+ int i = *str_pos;
if (c == '\0')
i = 0;
- else if (i < sizeof(env->gui.inbuf) - 1)
- env->gui.inbuf[i++] = c;
+ else if (i < GUI_BUFFER_LEN - 1)
+ str[i++] = c;
else
- i = sizeof(env->gui.inbuf) - 1; /* unnecessary, i think */
- env->gui.inbuf[i] = '\0';
- env->gui.inbuf_pos = i;
+ i = GUI_BUFFER_LEN - 1; /* unnecessary, i think */
+ str = '\0';
+ *str_pos = i;
}
/* accumulate digits, possibly call dial if in connected mode */
@@ -2214,11 +2240,12 @@
f.subclass = digit;
ast_queue_frame(o->owner, &f);
} else { /* no call, accumulate digits */
- append_char(env, digit);
+ append_char(env->gui.inbuf, &env->gui.inbuf_pos, digit);
}
}
/* this is a wrapper for actions that are available through the cli */
+/* TODO append arg to command and send the resulting string as cli command */
static void keypad_send_command(struct video_desc *env, char *command)
{
ast_log(LOG_WARNING, "keypad_send_command(%s) called\n", command);
@@ -2261,17 +2288,17 @@
struct chan_oss_pvt *o = find_desc(oss_active);
ast_log(LOG_WARNING, "keypad_pick_up called\n");
- if (o->owner) { /* someone is calling us, just answer */
+ if (o->owner) { /* someone is calling us, just answer */
struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
o->hookstate = 1;
o->cursound = -1;
o->nosound = 0;
ast_queue_frame(o->owner, &f);
- } else if (env->gui.inbuf_pos) { /* we dialed something, make the call */
+ } else if (env->gui.inbuf_pos) { /* we have someone to call */
ast_cli_command(env->gui.outfd, env->gui.inbuf);
}
- append_char(env, '\0'); /* clear buffer */
+ append_char(env->gui.inbuf, &env->gui.inbuf_pos, '\0'); /* clear buffer */
}
/* Print given text on the gui */
@@ -2302,12 +2329,6 @@
#endif
}
-static void keypad_write_message(struct video_desc *env)
-{
- ast_log(LOG_WARNING, "keypad_write_message called\n");
-}
-
-
/*
* Map the x, y coordinates to a keypad event according to
* the mask.
@@ -2344,6 +2365,9 @@
static void handle_button_event(struct video_desc *env, uint16_t x, uint16_t y)
{
uint8_t index;
+
+ /* for each click we come back in normal mode */
+ env->gui.text_mode = 0;
/* define keypad boundary */
if (x < env->in.rem_dpy.w)
@@ -2381,7 +2405,8 @@
case KEY_REMOTEVIDEO:
break;
case KEY_WRITEMESSAGE:
- keypad_write_message(env);
+ /* goes in text-mode */
+ env->gui.text_mode = 1;
break;
@@ -2389,6 +2414,11 @@
case KEY_REM_DPY:
break;
case KEY_LOC_DPY:
+ /* store points where the drag start
+ * and switch in drag mode */
+ env->gui.x_drag = x;
+ env->gui.y_drag = y;
+ env->gui.drag_mode = 1;
break;
case KEY_OUT_OF_KEYPAD:
break;
@@ -2401,6 +2431,91 @@
default:
ast_log(LOG_WARNING, "function not yet defined %i\n", index);
}
+}
+
+/*
+ * Handle SDL_KEYDOWN type event, put the key pressed
+ * in the dial buffer or in the text-message buffer,
+ * depending on the text_mode variable value.
+ *
+ * key is the SDLKey structure corresponding to the key pressed.
+ */
+static void handle_keyboard_input(struct video_desc *env, SDLKey key)
+{
+ if (env->gui.text_mode) {
+ /* append in the text-message buffer */
+ if (key == SDLK_RETURN) {
+ /* send the text message and return in normal mode */
+ env->gui.text_mode = 0;
+ keypad_send_command(env, "send text");
+ } else {
+ /* accumulate the key in the message buffer */
+ append_char(env->gui.msgbuf, &env->gui.msgbuf_pos, key);
+ }
+ }
+ else {
+ /* append in the dial buffer */
+ append_char(env->gui.inbuf, &env->gui.inbuf_pos, key);
+ }
+
+ return;
+}
+
+/*
+ * Check if the grab point is inside the X screen.
+ *
+ * x represent the new grab value
+ * limit represent the upper value to use
+ */
+static int boundary_checks(int x, int limit)
+{
+ /* res = (x <= 0) ? 0 : ((x > limit) ? limit : x); */
+
+ if (x <= 0)
+ return 0;
+
+ if (x > limit)
+ return limit;
+
+ return x;
+}
+
+/*
+ * Move the source of the captured video.
+ *
+ * x_final_drag and y_final_drag are the coordinates where the drag ends,
+ * start coordinares are in the gui_info structure.
+ */
+static void move_capture_source(struct video_desc *env, int x_final_drag, int y_final_drag)
+{
+ int new_x, new_y; /* new coordinates for grabbing local video */
+ int x = env->out.loc_src.x; /* temporary, used to print the old x value */
+ int y = env->out.loc_src.y; /* temporary, used to print the old y value */
+
+ /* compute new coordinates */
+ #define X_MAG 3
+ #define Y_MAG 2
+#if 0
+ /* move the source in the direction of the mouse */
+ new_x = env->out.loc_src.x + (x_final_drag - env->gui.x_drag) * X_MAG;
+ new_y = env->out.loc_src.y + (y_final_drag - env->gui.y_drag) * Y_MAG;
+#else
+ /* drag */
+ new_x = env->out.loc_src.x + (env->gui.x_drag - x_final_drag) * X_MAG;
+ new_y = env->out.loc_src.y + (env->gui.y_drag - y_final_drag) * Y_MAG;
+#endif
+
+ /* check boundary and let the source to grab from the new points */
+ env->out.loc_src.x = boundary_checks(new_x, env->out.X_max_width - env->out.loc_src.w);
+ env->out.loc_src.y = boundary_checks(new_y, env->out.X_max_height - env->out.loc_src.h);
+
+ ast_log(LOG_WARNING, "Computing new grab values, start grab points %d %d, \
+ end grab points (with magnifier) %d %d, \
+ boundary checked points %d %d\n",
+ x, y, new_x, new_y, env->out.loc_src.x , env->out.loc_src.y);
+
+return;
+
}
/*
@@ -2425,9 +2540,15 @@
ev[i].type, ev[i].button.x, ev[i].button.y);
#endif
switch (ev[i].type) {
+ case SDL_KEYDOWN:
+ handle_keyboard_input(env, ev[i].key.keysym.sym);
+ break;
case SDL_MOUSEBUTTONDOWN:
- /* ast_log(LOG_WARNING, "event SDL_MOUSEBUTTONDOWN %d\n", ev[i].type); */
handle_button_event(env, ev[i].button.x, ev[i].button.y);
+ break;
+ case SDL_MOUSEBUTTONUP:
+ if (env->gui.drag_mode != 0)
+ move_capture_source(env, ev[i].button.x, ev[i].button.y);
break;
}
@@ -2465,12 +2586,22 @@
/* Init the mask image used to grab the action. */
static int gui_init(struct video_desc *env)
{
+ /* initialize keypad status */
+ env->gui.text_mode = 0;
+ env->gui.drag_mode = 0;
+
+ /* initialize grab coordinates */
+ env->out.loc_src.x = 0;
+ env->out.loc_src.y = 0;
+
/* Load the keypad mask image */
env->gui.keypad_bg = get_keypad(env->keypad_mask);
if (env->gui.keypad_bg == NULL)
return -1;
- append_char(env, '\0');
+ /* initialize keyboard buffer */
+ append_char(env->gui.inbuf, &env->gui.inbuf_pos, '\0');
+ append_char(env->gui.msgbuf, &env->gui.msgbuf_pos, '\0');
#ifdef HAVE_SDL_TTF
/* Initialize SDL_ttf library and load font */
@@ -2552,6 +2683,8 @@
}
/* manage keypad events */
+ /* XXX here we should always check for events,
+ * otherwise the drag will not work */
if (env->gui_ok)
eventhandler(env);
More information about the asterisk-commits
mailing list