[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