mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-03 11:25:35 +00:00
more preparation for untangling of the various console_video stuff
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@94805 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -4,30 +4,73 @@
|
||||
* $Revision$
|
||||
*/
|
||||
|
||||
#include "asterisk.h"
|
||||
#include "console_video.h"
|
||||
#include "asterisk/lock.h"
|
||||
#include "asterisk/frame.h"
|
||||
#include "asterisk/utils.h" /* ast_calloc and ast_realloc */
|
||||
#include <math.h> /* sqrt */
|
||||
|
||||
enum kp_type { KP_NONE, KP_RECT, KP_CIRCLE };
|
||||
struct keypad_entry {
|
||||
int c; /* corresponding character */
|
||||
int x0, y0, x1, y1, h; /* arguments */
|
||||
enum kp_type type;
|
||||
};
|
||||
|
||||
#define GUI_BUFFER_LEN 256 /* buffer lenght used for input buffers */
|
||||
|
||||
struct keypad_entry; /* defined in console_gui.c */
|
||||
|
||||
/*! \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 */
|
||||
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
|
||||
int outfd; /* fd for output */
|
||||
SDL_Surface *keypad; /* the pixmap for the keypad */
|
||||
int kp_size, kp_used;
|
||||
struct keypad_entry *kp;
|
||||
};
|
||||
|
||||
static void cleanup_sdl(struct video_desc *env)
|
||||
{
|
||||
int i;
|
||||
struct gui_info *gui = env->gui;
|
||||
|
||||
if (gui) {
|
||||
#ifdef HAVE_SDL_TTF
|
||||
/* unload font file */
|
||||
if (env->gui.font) {
|
||||
TTF_CloseFont(env->gui.font);
|
||||
env->gui.font = NULL;
|
||||
if (gui->font) {
|
||||
TTF_CloseFont(gui->font);
|
||||
gui->font = NULL;
|
||||
}
|
||||
|
||||
/* uninitialize SDL_ttf library */
|
||||
if ( TTF_WasInit() )
|
||||
TTF_Quit();
|
||||
#endif
|
||||
if (gui->keypad)
|
||||
SDL_FreeSurface(gui->keypad);
|
||||
gui->keypad = NULL;
|
||||
/* XXX free the keys entries */
|
||||
ast_free(gui);
|
||||
env->gui = NULL;
|
||||
}
|
||||
|
||||
/* uninitialize the SDL environment */
|
||||
for (i = 0; i < WIN_MAX; i++) {
|
||||
if (env->win[i].bmp)
|
||||
SDL_FreeYUVOverlay(env->win[i].bmp);
|
||||
}
|
||||
if (env->gui.keypad)
|
||||
SDL_FreeSurface(env->gui.keypad);
|
||||
env->gui.keypad = NULL;
|
||||
SDL_Quit();
|
||||
env->screen = NULL; /* XXX check reference */
|
||||
bzero(env->win, sizeof(env->win));
|
||||
@@ -177,7 +220,7 @@ static void keypad_digit(struct video_desc *env, int digit)
|
||||
f.subclass = digit;
|
||||
ast_queue_frame(env->owner, &f);
|
||||
} else { /* no call, accumulate digits */
|
||||
append_char(env->gui.inbuf, &env->gui.inbuf_pos, digit);
|
||||
append_char(env->gui->inbuf, &env->gui->inbuf_pos, digit);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +229,7 @@ static void keypad_digit(struct video_desc *env, int digit)
|
||||
static void keypad_send_command(struct video_desc *env, char *command)
|
||||
{
|
||||
ast_log(LOG_WARNING, "keypad_send_command(%s) called\n", command);
|
||||
ast_cli_command(env->gui.outfd, command);
|
||||
ast_cli_command(env->gui->outfd, command);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -228,15 +271,17 @@ char *console_do_answer(int fd);
|
||||
*/
|
||||
static void keypad_pick_up(struct video_desc *env)
|
||||
{
|
||||
struct gui_info *gui = env->gui;
|
||||
|
||||
ast_log(LOG_WARNING, "keypad_pick_up called\n");
|
||||
|
||||
if (env->owner) { /* someone is calling us, just answer */
|
||||
console_do_answer(-1);
|
||||
} else if (env->gui.inbuf_pos) { /* we have someone to call */
|
||||
ast_cli_command(env->gui.outfd, env->gui.inbuf);
|
||||
} else if (gui->inbuf_pos) { /* we have someone to call */
|
||||
ast_cli_command(gui->outfd, gui->inbuf);
|
||||
}
|
||||
|
||||
append_char(env->gui.inbuf, &env->gui.inbuf_pos, '\0'); /* clear buffer */
|
||||
append_char(gui->inbuf, &gui->inbuf_pos, '\0'); /* clear buffer */
|
||||
}
|
||||
|
||||
#if 0 /* still unused */
|
||||
@@ -267,11 +312,12 @@ static int gui_output(struct video_desc *env, const char *text)
|
||||
SDL_Surface *output = NULL;
|
||||
SDL_Color color = {0, 0, 0}; /* text color */
|
||||
SDL_Rect dest = {env->win[WIN_KEYPAD].rect.x + x, y};
|
||||
struct gui_info *gui = env->gui;
|
||||
|
||||
/* clean surface each rewrite */
|
||||
SDL_BlitSurface(env->gui.keypad, NULL, env->screen, &env->win[WIN_KEYPAD].rect);
|
||||
SDL_BlitSurface(gui->keypad, NULL, env->screen, &env->win[WIN_KEYPAD].rect);
|
||||
|
||||
output = TTF_RenderText_Solid(env->gui.font, text, color);
|
||||
output = TTF_RenderText_Solid(gui->font, text, color);
|
||||
if (output == NULL) {
|
||||
ast_log(LOG_WARNING, "Cannot render text on gui - %s\n", TTF_GetError());
|
||||
return 1;
|
||||
@@ -279,7 +325,7 @@ static int gui_output(struct video_desc *env, const char *text)
|
||||
|
||||
SDL_BlitSurface(output, NULL, env->screen, &dest);
|
||||
|
||||
SDL_UpdateRects(env->gui.keypad, 1, &env->win[WIN_KEYPAD].rect);
|
||||
SDL_UpdateRects(gui->keypad, 1, &env->win[WIN_KEYPAD].rect);
|
||||
SDL_FreeSurface(output);
|
||||
return 0; /* success */
|
||||
#endif
|
||||
@@ -300,8 +346,12 @@ static void handle_button_event(struct video_desc *env, SDL_MouseButtonEvent but
|
||||
{
|
||||
uint8_t index = KEY_OUT_OF_KEYPAD; /* the key or region of the display we clicked on */
|
||||
|
||||
#if 0
|
||||
ast_log(LOG_WARNING, "event %d %d have %d/%d regions at %p\n",
|
||||
button.x, button.y, env->gui->kp_used, env->gui->kp_size, env->gui->kp);
|
||||
#endif
|
||||
/* for each click we come back in normal mode */
|
||||
env->gui.text_mode = 0;
|
||||
env->gui->text_mode = 0;
|
||||
|
||||
/* define keypad boundary */
|
||||
if (button.x < env->in.rem_dpy.w)
|
||||
@@ -310,11 +360,11 @@ static void handle_button_event(struct video_desc *env, SDL_MouseButtonEvent but
|
||||
index = KEY_LOC_DPY; /* click on local video */
|
||||
else if (button.y > env->out.keypad_dpy.h)
|
||||
index = KEY_OUT_OF_KEYPAD; /* click outside the keypad */
|
||||
else if (env->gui.kp) {
|
||||
else if (env->gui->kp) {
|
||||
int i;
|
||||
for (i = 0; i < env->gui.kp_used; i++) {
|
||||
if (kp_match_area(&env->gui.kp[i], button.x - env->in.rem_dpy.w, button.y)) {
|
||||
index = env->gui.kp[i].c;
|
||||
for (i = 0; i < env->gui->kp_used; i++) {
|
||||
if (kp_match_area(&env->gui->kp[i], button.x - env->in.rem_dpy.w, button.y)) {
|
||||
index = env->gui->kp[i].c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -347,7 +397,7 @@ static void handle_button_event(struct video_desc *env, SDL_MouseButtonEvent but
|
||||
break;
|
||||
case KEY_WRITEMESSAGE:
|
||||
/* goes in text-mode */
|
||||
env->gui.text_mode = 1;
|
||||
env->gui->text_mode = 1;
|
||||
break;
|
||||
|
||||
|
||||
@@ -358,9 +408,9 @@ static void handle_button_event(struct video_desc *env, SDL_MouseButtonEvent but
|
||||
if (index == KEY_LOC_DPY) {
|
||||
/* store points where the drag start
|
||||
* and switch in drag mode */
|
||||
env->gui.x_drag = button.x;
|
||||
env->gui.y_drag = button.y;
|
||||
env->gui.drag_mode = 1;
|
||||
env->gui->x_drag = button.x;
|
||||
env->gui->y_drag = button.y;
|
||||
env->gui->drag_mode = 1;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
@@ -394,20 +444,20 @@ static void handle_button_event(struct video_desc *env, SDL_MouseButtonEvent but
|
||||
*/
|
||||
static void handle_keyboard_input(struct video_desc *env, SDLKey key)
|
||||
{
|
||||
if (env->gui.text_mode) {
|
||||
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;
|
||||
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);
|
||||
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);
|
||||
append_char(env->gui->inbuf, &env->gui->inbuf_pos, key);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -445,11 +495,11 @@ static void move_capture_source(struct video_desc *env, int x_final_drag, int y_
|
||||
|
||||
/* move the origin */
|
||||
#define POLARITY -1 /* +1 or -1 depending on the desired direction */
|
||||
new_x = x + POLARITY*move_accel(x_final_drag - env->gui.x_drag) * 3;
|
||||
new_y = y + POLARITY*move_accel(y_final_drag - env->gui.y_drag) * 3;
|
||||
new_x = x + POLARITY*move_accel(x_final_drag - env->gui->x_drag) * 3;
|
||||
new_y = y + POLARITY*move_accel(y_final_drag - env->gui->y_drag) * 3;
|
||||
#undef POLARITY
|
||||
env->gui.x_drag = x_final_drag; /* update origin */
|
||||
env->gui.y_drag = y_final_drag;
|
||||
env->gui->x_drag = x_final_drag; /* update origin */
|
||||
env->gui->y_drag = y_final_drag;
|
||||
|
||||
/* check boundary and let the source to grab from the new points */
|
||||
env->out.loc_src.x = boundary_checks(new_x, env->out.screen_width - env->out.loc_src.w);
|
||||
@@ -483,16 +533,16 @@ static void eventhandler(struct video_desc *env)
|
||||
handle_keyboard_input(env, ev[i].key.keysym.sym);
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
if (env->gui.drag_mode != 0)
|
||||
if (env->gui->drag_mode != 0)
|
||||
move_capture_source(env, ev[i].motion.x, ev[i].motion.y);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
handle_button_event(env, ev[i].button);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
if (env->gui.drag_mode != 0) {
|
||||
if (env->gui->drag_mode != 0) {
|
||||
move_capture_source(env, ev[i].button.x, ev[i].button.y);
|
||||
env->gui.drag_mode = 0;
|
||||
env->gui->drag_mode = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -529,43 +579,50 @@ static SDL_Surface *get_keypad(const char *file)
|
||||
|
||||
/* TODO: consistency checks, check for bpp, widht and height */
|
||||
/* Init the mask image used to grab the action. */
|
||||
static int gui_init(struct video_desc *env)
|
||||
static struct gui_info *gui_init(struct video_desc *env)
|
||||
{
|
||||
struct gui_info *gui = ast_calloc(1, sizeof(*gui));
|
||||
|
||||
if (gui == NULL)
|
||||
return NULL;
|
||||
/* initialize keypad status */
|
||||
env->gui.text_mode = 0;
|
||||
env->gui.drag_mode = 0;
|
||||
gui->text_mode = 0;
|
||||
gui->drag_mode = 0;
|
||||
|
||||
/* initialize grab coordinates */
|
||||
env->out.loc_src.x = 0;
|
||||
env->out.loc_src.y = 0;
|
||||
|
||||
/* initialize keyboard buffer */
|
||||
append_char(env->gui.inbuf, &env->gui.inbuf_pos, '\0');
|
||||
append_char(env->gui.msgbuf, &env->gui.msgbuf_pos, '\0');
|
||||
append_char(gui->inbuf, &gui->inbuf_pos, '\0');
|
||||
append_char(gui->msgbuf, &gui->msgbuf_pos, '\0');
|
||||
|
||||
#ifdef HAVE_SDL_TTF
|
||||
/* Initialize SDL_ttf library and load font */
|
||||
if (TTF_Init() == -1) {
|
||||
ast_log(LOG_WARNING, "Unable to init SDL_ttf, no output available\n");
|
||||
return -1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
#define GUI_FONTSIZE 28
|
||||
env->gui.font = TTF_OpenFont( env->keypad_font, GUI_FONTSIZE);
|
||||
if (!env->gui.font) {
|
||||
gui->font = TTF_OpenFont( env->keypad_font, GUI_FONTSIZE);
|
||||
if (!gui->font) {
|
||||
ast_log(LOG_WARNING, "Unable to load font %s, no output available\n", env->keypad_font);
|
||||
return -1;
|
||||
goto error;
|
||||
}
|
||||
ast_log(LOG_WARNING, "Loaded font %s\n", env->keypad_font);
|
||||
#endif
|
||||
|
||||
env->gui.outfd = open ("/dev/null", O_WRONLY); /* discard output, temporary */
|
||||
if ( env->gui.outfd < 0 ) {
|
||||
gui->outfd = open ("/dev/null", O_WRONLY); /* discard output, temporary */
|
||||
if (gui->outfd < 0) {
|
||||
ast_log(LOG_WARNING, "Unable output fd\n");
|
||||
return -1;
|
||||
goto error;
|
||||
}
|
||||
return gui;
|
||||
|
||||
return 0;
|
||||
error:
|
||||
ast_free(gui);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* setup an sdl overlay and associated info, return 0 on success, != 0 on error */
|
||||
@@ -590,14 +647,14 @@ static void keypad_setup(struct video_desc *env)
|
||||
void *p = NULL;
|
||||
off_t l = 0;
|
||||
|
||||
if (env->gui.keypad)
|
||||
if (env->gui->keypad)
|
||||
return;
|
||||
env->gui.keypad = get_keypad(env->keypad_file);
|
||||
if (!env->gui.keypad)
|
||||
env->gui->keypad = get_keypad(env->keypad_file);
|
||||
if (!env->gui->keypad)
|
||||
return;
|
||||
|
||||
env->out.keypad_dpy.w = env->gui.keypad->w;
|
||||
env->out.keypad_dpy.h = env->gui.keypad->h;
|
||||
env->out.keypad_dpy.w = env->gui->keypad->w;
|
||||
env->out.keypad_dpy.h = env->gui->keypad->h;
|
||||
/*
|
||||
* If the keypad image has a comment field, try to read
|
||||
* the button location from there. The block must be
|
||||
@@ -631,7 +688,7 @@ static void keypad_setup(struct video_desc *env)
|
||||
for (s = p; s < e - 20 ; s++) {
|
||||
if (!memcmp(s, region, reg_len)) { /* keyword found */
|
||||
/* reset previous entries */
|
||||
keypad_cfg_read(&env->gui, "reset");
|
||||
keypad_cfg_read(env->gui, "reset");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -652,7 +709,7 @@ static void keypad_setup(struct video_desc *env)
|
||||
break;
|
||||
if (*s1 == '>') /* skip => */
|
||||
s1++;
|
||||
keypad_cfg_read(&env->gui, ast_skip_blanks(s1));
|
||||
keypad_cfg_read(env->gui, ast_skip_blanks(s1));
|
||||
/* now wait for a newline */
|
||||
s1 = s;
|
||||
while (s1 < e - 20 && !index("\r\n", *s1) && *s1 < 128)
|
||||
@@ -686,9 +743,17 @@ static void sdl_setup(struct video_desc *env)
|
||||
* - on the left, the remote video;
|
||||
* - on the center, the keypad
|
||||
* - on the right, the local video
|
||||
* We need to read in the skin for the keypad before creating the main
|
||||
* SDL window, because the size is only known here.
|
||||
*/
|
||||
|
||||
keypad_setup(env);
|
||||
env->gui = gui_init(env);
|
||||
ast_log(LOG_WARNING, "gui_init returned %p\n", env->gui);
|
||||
if (env->gui) {
|
||||
keypad_setup(env);
|
||||
ast_log(LOG_WARNING, "keypad_setup returned %p %d\n",
|
||||
env->gui->keypad, env->gui->kp_used);
|
||||
}
|
||||
#define BORDER 5 /* border around our windows */
|
||||
maxw = env->in.rem_dpy.w + env->out.loc_dpy.w + env->out.keypad_dpy.w;
|
||||
maxh = MAX( MAX(env->in.rem_dpy.h, env->out.loc_dpy.h), env->out.keypad_dpy.h);
|
||||
@@ -712,13 +777,13 @@ static void sdl_setup(struct video_desc *env)
|
||||
/* display the skin, but do not free it as we need it later to
|
||||
* restore text areas and maybe sliders too.
|
||||
*/
|
||||
if (env->gui.keypad) {
|
||||
if (env->gui && env->gui->keypad) {
|
||||
struct SDL_Rect *dest = &env->win[WIN_KEYPAD].rect;
|
||||
dest->x = 2*BORDER + env->in.rem_dpy.w;
|
||||
dest->y = BORDER;
|
||||
dest->w = env->gui.keypad->w;
|
||||
dest->h = env->gui.keypad->h;
|
||||
SDL_BlitSurface(env->gui.keypad, NULL, env->screen, dest);
|
||||
dest->w = env->gui->keypad->w;
|
||||
dest->h = env->gui->keypad->h;
|
||||
SDL_BlitSurface(env->gui->keypad, NULL, env->screen, dest);
|
||||
SDL_UpdateRects(env->screen, 1, dest);
|
||||
}
|
||||
env->in.dec_in_cur = &env->in.dec_in[0];
|
||||
@@ -765,15 +830,6 @@ static int kp_match_area(const struct keypad_entry *e, int x, int y)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* read a keypad entry line in the format
|
||||
* reset
|
||||
* token circle xc yc diameter
|
||||
* token circle xc yc x1 y1 h # ellipse, main diameter and height
|
||||
* token rect x0 y0 x1 y1 h # rectangle with main side and eight
|
||||
* token is the token to be returned, either a character or a symbol
|
||||
* as KEY_* above
|
||||
*/
|
||||
struct _s_k { const char *s; int k; };
|
||||
static struct _s_k gui_key_map[] = {
|
||||
{"PICK_UP", KEY_PICK_UP },
|
||||
@@ -789,12 +845,24 @@ static struct _s_k gui_key_map[] = {
|
||||
{"GUI_CLOSE", KEY_GUI_CLOSE },
|
||||
{NULL, 0 } };
|
||||
|
||||
/*! \brief read a keypad entry line in the format
|
||||
* reset
|
||||
* token circle xc yc diameter
|
||||
* token circle xc yc x1 y1 h # ellipse, main diameter and height
|
||||
* token rect x0 y0 x1 y1 h # rectangle with main side and eight
|
||||
* token is the token to be returned, either a character or a symbol
|
||||
* as KEY_* above
|
||||
* Return 1 on success, 0 on error.
|
||||
*/
|
||||
static int keypad_cfg_read(struct gui_info *gui, const char *val)
|
||||
{
|
||||
struct keypad_entry e;
|
||||
char s1[16], s2[16];
|
||||
int i, ret = 0;
|
||||
|
||||
if (gui == NULL || val == NULL)
|
||||
return 0;
|
||||
|
||||
bzero(&e, sizeof(e));
|
||||
i = sscanf(val, "%14s %14s %d %d %d %d %d",
|
||||
s1, s2, &e.x0, &e.y0, &e.x1, &e.y1, &e.h);
|
||||
@@ -876,5 +944,6 @@ static int keypad_cfg_read(struct gui_info *gui, const char *val)
|
||||
if (gui->kp_size == gui->kp_used)
|
||||
return 0;
|
||||
gui->kp[gui->kp_used++] = e;
|
||||
ast_log(LOG_WARNING, "now %d regions\n", gui->kp_used);
|
||||
return 1;
|
||||
}
|
||||
|
Reference in New Issue
Block a user