#include "asterisk.h"
#include "console_video.h"
#include "asterisk/lock.h"
#include "asterisk/frame.h"
#include "asterisk/utils.h"
#include <math.h>
#include <SDL/SDL.h>
Go to the source code of this file.
Data Structures | |
struct | _s_k |
struct | display_window |
struct | gui_info |
struct | keypad_entry |
Defines | |
#define | BORDER 5 |
#define | FONT_H 20 |
#define | FONT_W 9 |
#define | MY_EV (SDL_MOUSEBUTTONDOWN|SDL_KEYDOWN) |
#define | N_EVENTS 32 |
#define | POLARITY -1 |
Enumerations | |
enum | { WIN_LOCAL, WIN_REMOTE, WIN_KEYPAD, WIN_MAX } |
enum | kp_type { KP_NONE, KP_RECT, KP_CIRCLE } |
enum | skin_area { KEY_PICK_UP = 128, KEY_HANG_UP = 129, KEY_MUTE = 130, KEY_AUTOANSWER = 131, KEY_SENDVIDEO = 132, KEY_LOCALVIDEO = 133, KEY_REMOTEVIDEO = 134, KEY_FLASH = 136, KEY_MESSAGEBOARD = 140, KEY_DIALEDBOARD = 141, KEY_EDITBOARD = 142, KEY_GUI_CLOSE = 199, KEY_KEYPAD = 200, KEY_FONT = 201, KEY_MESSAGE = 202, KEY_DIALED = 203, KEY_EDIT = 204, KEY_OUT_OF_KEYPAD = 241, KEY_REM_DPY = 242, KEY_LOC_DPY = 243, KEY_RESET = 253, KEY_NONE = 254, KEY_DIGIT_BACKGROUND = 255 } |
Functions | |
board * | board_setup (SDL_Surface *screen, SDL_Rect *dest, SDL_Surface *font, SDL_Rect *font_rects) |
static struct gui_info * | cleanup_sdl (struct gui_info *gui) |
free the resources in struct gui_info and the descriptor itself. Return NULL so we can assign the value back to the descriptor in case. | |
int | compute_drag (int *start, int end, int magnifier) |
char * | console_do_answer (int fd) |
static void | eventhandler (struct video_desc *env, const char *caption) |
refresh the screen, and also grab a bunch of events. | |
static void | grabber_move (struct video_out_desc *, int dx, int dy) |
static struct gui_info * | gui_init (const char *keypad_file, const char *font) |
static int | gui_map_token (const char *s) |
static void | handle_keyboard_input (struct video_desc *env, SDL_keysym *ks) |
static void | handle_mousedown (struct video_desc *env, SDL_MouseButtonEvent button) |
static void | init_board (struct gui_info *gui, struct board **dst, SDL_Rect *r, int dx, int dy) |
initialize the boards we have in the keypad | |
static int | keypad_cfg_read (struct gui_info *gui, const char *val) |
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 void | keypad_digit (struct video_desc *env, int digit) |
static void | keypad_pick_up (struct video_desc *env) |
static void | keypad_setup (struct gui_info *gui, const char *kp_file) |
static char * | keypad_toggle (struct video_desc *env, int index) |
static int | kp_match_area (const struct keypad_entry *e, int x, int y) |
static SDL_Surface * | load_image (const char *file) |
static char | map_key (SDL_keysym *ks) |
static void | sdl_setup (struct video_desc *env) |
[re]set the main sdl window, useful in case of resize. We can tell the first from subsequent calls from the value of env->gui, which is NULL the first time. | |
static void | set_drag (struct drag_info *drag, int x, int y, enum drag_window win) |
static int | set_win (SDL_Surface *screen, struct display_window *win, int fmt, int w, int h, int x, int y) |
static void | show_frame (struct video_desc *env, int out) |
static int | video_geom (struct fbuf_t *b, const char *s) |
Variables | |
static struct _s_k | gui_key_map [] |
static const char * | us_kbd_map [] |
#define BORDER 5 |
Referenced by sdl_setup().
#define FONT_H 20 |
#define FONT_W 9 |
#define MY_EV (SDL_MOUSEBUTTONDOWN|SDL_KEYDOWN) |
#define N_EVENTS 32 |
Referenced by eventhandler().
#define POLARITY -1 |
Referenced by compute_drag().
anonymous enum |
enum kp_type |
enum skin_area |
Definition at line 206 of file console_gui.c.
00206 { 00207 /* answer/close functions */ 00208 KEY_PICK_UP = 128, 00209 KEY_HANG_UP = 129, 00210 00211 KEY_MUTE = 130, 00212 KEY_AUTOANSWER = 131, 00213 KEY_SENDVIDEO = 132, 00214 KEY_LOCALVIDEO = 133, 00215 KEY_REMOTEVIDEO = 134, 00216 KEY_FLASH = 136, 00217 00218 /* sensitive areas for the various text windows */ 00219 KEY_MESSAGEBOARD = 140, 00220 KEY_DIALEDBOARD = 141, 00221 KEY_EDITBOARD = 142, 00222 00223 KEY_GUI_CLOSE = 199, /* close gui */ 00224 /* regions of the skin - displayed area, fonts, etc. 00225 * XXX NOTE these are not sensitive areas. 00226 */ 00227 KEY_KEYPAD = 200, /* the keypad - default to the whole image */ 00228 KEY_FONT = 201, /* the font. Maybe not really useful */ 00229 KEY_MESSAGE = 202, /* area for incoming messages */ 00230 KEY_DIALED = 203, /* area for dialed numbers */ 00231 KEY_EDIT = 204, /* area for editing user input */ 00232 00233 /* areas outside the keypad - simulated */ 00234 KEY_OUT_OF_KEYPAD = 241, 00235 KEY_REM_DPY = 242, 00236 KEY_LOC_DPY = 243, 00237 KEY_RESET = 253, /* the 'reset' keyword */ 00238 KEY_NONE = 254, /* invalid area */ 00239 KEY_DIGIT_BACKGROUND = 255, /* other areas within the keypad */ 00240 };
struct board* board_setup | ( | SDL_Surface * | screen, | |
SDL_Rect * | dest, | |||
SDL_Surface * | font, | |||
SDL_Rect * | font_rects | |||
) |
free the resources in struct gui_info and the descriptor itself. Return NULL so we can assign the value back to the descriptor in case.
Definition at line 112 of file console_gui.c.
References ast_free, display_window::bmp, gui_info::font, gui_info::keypad, gui_info::kp, gui_info::outfd, gui_info::win, and WIN_MAX.
Referenced by sdl_setup().
00113 { 00114 int i; 00115 00116 if (gui == NULL) 00117 return NULL; 00118 00119 /* unload font file */ 00120 if (gui->font) { 00121 SDL_FreeSurface(gui->font); 00122 gui->font = NULL; 00123 } 00124 00125 if (gui->outfd > -1) 00126 close(gui->outfd); 00127 if (gui->keypad) 00128 SDL_FreeSurface(gui->keypad); 00129 gui->keypad = NULL; 00130 if (gui->kp) 00131 ast_free(gui->kp); 00132 00133 /* uninitialize the SDL environment */ 00134 for (i = 0; i < WIN_MAX; i++) { 00135 if (gui->win[i].bmp) 00136 SDL_FreeYUVOverlay(gui->win[i].bmp); 00137 } 00138 memset(gui, '\0', sizeof(gui)); 00139 ast_free(gui); 00140 SDL_Quit(); 00141 return NULL; 00142 }
int compute_drag | ( | int * | start, | |
int | end, | |||
int | magnifier | |||
) |
Definition at line 523 of file console_gui.c.
References POLARITY.
Referenced by eventhandler().
00524 { 00525 int delta = end - *start; 00526 #define POLARITY -1 00527 /* add a small quadratic term */ 00528 delta += delta * delta * (delta > 0 ? 1 : -1 )/100; 00529 delta *= POLARITY * magnifier; 00530 #undef POLARITY 00531 *start = end; 00532 return delta; 00533 }
char* console_do_answer | ( | int | fd | ) |
static void eventhandler | ( | struct video_desc * | env, | |
const char * | caption | |||
) | [static] |
refresh the screen, and also grab a bunch of events.
Definition at line 544 of file console_gui.c.
References ast_log(), gui_info::bd_msg, compute_drag(), gui_info::drag, DRAG_LOCAL, DRAG_MESSAGE, DRAG_NONE, drag_info::drag_window, grabber_move(), handle_keyboard_input(), handle_mousedown(), LOG_WARNING, move_message_board(), N_EVENTS, type, drag_info::x_start, and drag_info::y_start.
00545 { 00546 struct gui_info *gui = env->gui; 00547 struct drag_info *drag; 00548 #define N_EVENTS 32 00549 int i, n; 00550 SDL_Event ev[N_EVENTS]; 00551 00552 if (!gui) 00553 return; 00554 drag = &gui->drag; 00555 if (caption) 00556 SDL_WM_SetCaption(caption, NULL); 00557 00558 #define MY_EV (SDL_MOUSEBUTTONDOWN|SDL_KEYDOWN) 00559 while ( (n = SDL_PeepEvents(ev, N_EVENTS, SDL_GETEVENT, SDL_ALLEVENTS)) > 0) { 00560 for (i = 0; i < n; i++) { 00561 #if 0 00562 ast_log(LOG_WARNING, "------ event %d at %d %d\n", 00563 ev[i].type, ev[i].button.x, ev[i].button.y); 00564 #endif 00565 switch (ev[i].type) { 00566 case SDL_KEYDOWN: 00567 handle_keyboard_input(env, &ev[i].key.keysym); 00568 break; 00569 case SDL_MOUSEMOTION: 00570 case SDL_MOUSEBUTTONUP: 00571 if (drag->drag_window == DRAG_LOCAL) { 00572 /* move the capture source */ 00573 int dx = compute_drag(&drag->x_start, ev[i].motion.x, 3); 00574 int dy = compute_drag(&drag->y_start, ev[i].motion.y, 3); 00575 grabber_move(&env->out, dx, dy); 00576 } else if (drag->drag_window == DRAG_MESSAGE) { 00577 /* scroll up/down the window */ 00578 int dy = compute_drag(&drag->y_start, ev[i].motion.y, 1); 00579 move_message_board(gui->bd_msg, dy); 00580 } 00581 if (ev[i].type == SDL_MOUSEBUTTONUP) 00582 drag->drag_window = DRAG_NONE; 00583 break; 00584 case SDL_MOUSEBUTTONDOWN: 00585 handle_mousedown(env, ev[i].button); 00586 break; 00587 } 00588 } 00589 } 00590 if (1) { 00591 struct timeval b, a = ast_tvnow(); 00592 int i; 00593 //SDL_Lock_EventThread(); 00594 SDL_PumpEvents(); 00595 b = ast_tvnow(); 00596 i = ast_tvdiff_ms(b, a); 00597 if (i > 3) 00598 fprintf(stderr, "-------- SDL_PumpEvents took %dms\n", i); 00599 //SDL_Unlock_EventThread(); 00600 } 00601 }
static void grabber_move | ( | struct video_out_desc * | , | |
int | dx, | |||
int | dy | |||
) | [static] |
Referenced by eventhandler().
static struct gui_info* gui_init | ( | const char * | keypad_file, | |
const char * | font | |||
) | [static] |
Definition at line 622 of file console_gui.c.
References ast_calloc, ast_free, ast_log(), ast_strlen_zero(), DRAG_NONE, FONT_H, FONT_W, keypad_setup(), KO_MESSAGE, load_image(), and LOG_WARNING.
Referenced by sdl_setup().
00623 { 00624 struct gui_info *gui = ast_calloc(1, sizeof(*gui)); 00625 00626 if (gui == NULL) 00627 return NULL; 00628 /* initialize keypad status */ 00629 gui->kb_output = KO_MESSAGE; /* XXX temp */ 00630 gui->drag.drag_window = DRAG_NONE; 00631 gui->outfd = -1; 00632 00633 keypad_setup(gui, keypad_file); 00634 if (gui->keypad == NULL) /* no keypad, we are done */ 00635 return gui; 00636 /* XXX load image */ 00637 if (!ast_strlen_zero(font)) { 00638 int i; 00639 SDL_Rect *r; 00640 00641 gui->font = load_image(font); 00642 if (!gui->font) { 00643 ast_log(LOG_WARNING, "Unable to load font %s, no output available\n", font); 00644 goto error; 00645 } 00646 ast_log(LOG_WARNING, "Loaded font %s\n", font); 00647 /* XXX hardwired constants - 3 rows of 32 chars */ 00648 r = gui->font_rects; 00649 #define FONT_H 20 00650 #define FONT_W 9 00651 for (i = 0; i < 96; r++, i++) { 00652 r->x = (i % 32 ) * FONT_W; 00653 r->y = (i / 32 ) * FONT_H; 00654 r->w = FONT_W; 00655 r->h = FONT_H; 00656 } 00657 } 00658 00659 gui->outfd = open ("/dev/null", O_WRONLY); /* discard output, temporary */ 00660 if (gui->outfd < 0) { 00661 ast_log(LOG_WARNING, "Unable output fd\n"); 00662 goto error; 00663 } 00664 return gui; 00665 00666 error: 00667 ast_free(gui); 00668 return NULL; 00669 }
static int gui_map_token | ( | const char * | s | ) | [static] |
Definition at line 912 of file console_gui.c.
References gui_key_map, _s_k::k, KEY_NONE, and _s_k::s.
Referenced by keypad_cfg_read().
00913 { 00914 /* map the string into token to be returned */ 00915 int i = atoi(s); 00916 struct _s_k *p; 00917 if (i > 0 || s[1] == '\0') /* numbers or single characters */ 00918 return (i > 9) ? i : s[0]; 00919 for (p = gui_key_map; p->s; p++) { 00920 if (!strcasecmp(p->s, s)) 00921 return p->k; 00922 } 00923 return KEY_NONE; /* not found */ 00924 }
static void handle_keyboard_input | ( | struct video_desc * | env, | |
SDL_keysym * | ks | |||
) | [static] |
Definition at line 493 of file console_gui.c.
References gui_info::bd_msg, buf, gui_info::kb_output, keypad_pick_up(), KO_DIALED, KO_INPUT, KO_MESSAGE, map_key(), and print_message().
Referenced by eventhandler().
00494 { 00495 char buf[2] = { map_key(ks), '\0' }; 00496 struct gui_info *gui = env->gui; 00497 if (buf[0] == 0) /* modifier ? */ 00498 return; 00499 switch (gui->kb_output) { 00500 default: 00501 break; 00502 case KO_INPUT: /* to be completed */ 00503 break; 00504 case KO_MESSAGE: 00505 if (gui->bd_msg) { 00506 print_message(gui->bd_msg, buf); 00507 if (buf[0] == '\r' || buf[0] == '\n') { 00508 keypad_pick_up(env); 00509 } 00510 } 00511 break; 00512 00513 case KO_DIALED: /* to be completed */ 00514 break; 00515 } 00516 00517 return; 00518 }
static void handle_mousedown | ( | struct video_desc * | env, | |
SDL_MouseButtonEvent | button | |||
) | [static] |
Definition at line 360 of file console_gui.c.
References ast_log(), keypad_entry::c, gui_info::drag, DRAG_NONE, drag_info::drag_window, KEY_LOC_DPY, KEY_OUT_OF_KEYPAD, KEY_REM_DPY, gui_info::keypad, gui_info::kp, kp_match_area(), gui_info::kp_size, gui_info::kp_used, and LOG_WARNING.
Referenced by eventhandler().
00361 { 00362 uint8_t index = KEY_OUT_OF_KEYPAD; /* the key or region of the display we clicked on */ 00363 struct gui_info *gui = env->gui; 00364 00365 #if 0 00366 ast_log(LOG_WARNING, "event %d %d have %d/%d regions at %p\n", 00367 button.x, button.y, gui->kp_used, gui->kp_size, gui->kp); 00368 #endif 00369 /* for each mousedown we end previous drag */ 00370 gui->drag.drag_window = DRAG_NONE; 00371 00372 /* define keypad boundary */ 00373 if (button.x < env->rem_dpy.w) 00374 index = KEY_REM_DPY; /* click on remote video */ 00375 else if (button.x > env->rem_dpy.w + gui->keypad->w) 00376 index = KEY_LOC_DPY; /* click on local video */ 00377 else if (button.y > gui->keypad->h) 00378 index = KEY_OUT_OF_KEYPAD; /* click outside the keypad */ 00379 else if (gui->kp) { 00380 int i; 00381 for (i = 0; i < gui->kp_used; i++) { 00382 if (kp_match_area(&gui->kp[i], button.x - env->rem_dpy.w, button.y)) { 00383 index = gui->kp[i].c; 00384 break; 00385 } 00386 } 00387 } 00388 00389 /* exec the function */ 00390 if (index < 128) { /* surely clicked on the keypad, don't care which key */ 00391 keypad_digit(env, index); 00392 return; 00393 } 00394 switch (index) { 00395 /* answer/close function */ 00396 case KEY_PICK_UP: 00397 keypad_pick_up(env); 00398 break; 00399 case KEY_HANG_UP: 00400 ast_cli_command(gui->outfd, "console hangup"); 00401 break; 00402 00403 /* other functions */ 00404 case KEY_MUTE: 00405 case KEY_AUTOANSWER: 00406 case KEY_SENDVIDEO: 00407 keypad_toggle(env, index); 00408 break; 00409 00410 case KEY_LOCALVIDEO: 00411 break; 00412 case KEY_REMOTEVIDEO: 00413 break; 00414 00415 case KEY_MESSAGEBOARD: 00416 if (button.button == SDL_BUTTON_LEFT) 00417 set_drag(&gui->drag, button.x, button.y, DRAG_MESSAGE); 00418 break; 00419 00420 /* press outside the keypad. right increases size, center decreases, left drags */ 00421 case KEY_LOC_DPY: 00422 case KEY_REM_DPY: 00423 if (button.button == SDL_BUTTON_LEFT) { 00424 if (index == KEY_LOC_DPY) 00425 set_drag(&gui->drag, button.x, button.y, DRAG_LOCAL); 00426 break; 00427 } else { 00428 char buf[128]; 00429 struct fbuf_t *fb = index == KEY_LOC_DPY ? &env->loc_dpy : &env->rem_dpy; 00430 sprintf(buf, "%c%dx%d", button.button == SDL_BUTTON_RIGHT ? '>' : '<', 00431 fb->w, fb->h); 00432 video_geom(fb, buf); 00433 sdl_setup(env); 00434 } 00435 break; 00436 case KEY_OUT_OF_KEYPAD: 00437 break; 00438 00439 case KEY_DIGIT_BACKGROUND: 00440 break; 00441 default: 00442 ast_log(LOG_WARNING, "function not yet defined %i\n", index); 00443 } 00444 }
static void init_board | ( | struct gui_info * | gui, | |
struct board ** | dst, | |||
SDL_Rect * | r, | |||
int | dx, | |||
int | dy | |||
) | [static] |
initialize the boards we have in the keypad
Definition at line 746 of file console_gui.c.
References board_setup(), gui_info::font, gui_info::font_rects, and gui_info::screen.
Referenced by sdl_setup().
00747 { 00748 if (r[0].w == 0 || r[0].h == 0) 00749 return; /* not available */ 00750 r[1] = r[0]; /* copy geometry */ 00751 r[1].x += dx; /* add offset of main window */ 00752 r[1].y += dy; 00753 if (*dst == NULL) { /* initial call */ 00754 *dst = board_setup(gui->screen, &r[1], gui->font, gui->font_rects); 00755 } else { 00756 /* call a refresh */ 00757 } 00758 }
static int keypad_cfg_read | ( | struct gui_info * | gui, | |
const char * | val | |||
) | [static] |
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.
Definition at line 935 of file console_gui.c.
References ast_calloc, ast_log(), ast_realloc, gui_map_token(), KEY_DIALED, KEY_EDIT, KEY_FONT, KEY_KEYPAD, KEY_MESSAGE, KEY_NONE, KEY_RESET, gui_info::kp, KP_CIRCLE, gui_info::kp_dialed, gui_info::kp_edit, gui_info::kp_msg, KP_RECT, gui_info::kp_rect, gui_info::kp_size, gui_info::kp_used, and LOG_WARNING.
Referenced by keypad_setup().
00936 { 00937 struct keypad_entry e; 00938 SDL_Rect *r = NULL; 00939 char s1[16], s2[16]; 00940 int i, ret = 0; /* default, error */ 00941 00942 if (gui == NULL || val == NULL) 00943 return 0; 00944 00945 s1[0] = s2[0] = '\0'; 00946 memset(&e, '\0', sizeof(e)); 00947 i = sscanf(val, "%14s %14s %d %d %d %d %d", 00948 s1, s2, &e.x0, &e.y0, &e.x1, &e.y1, &e.h); 00949 00950 e.c = gui_map_token(s1); 00951 if (e.c == KEY_NONE) 00952 return 0; /* nothing found */ 00953 switch (i) { 00954 default: 00955 break; 00956 case 1: /* only "reset" is allowed */ 00957 if (e.c != KEY_RESET) 00958 break; 00959 if (gui->kp) 00960 gui->kp_used = 0; 00961 break; 00962 case 5: 00963 if (e.c == KEY_KEYPAD) /* active keypad area */ 00964 r = &gui->kp_rect; 00965 else if (e.c == KEY_MESSAGE) 00966 r = gui->kp_msg; 00967 else if (e.c == KEY_DIALED) 00968 r = gui->kp_dialed; 00969 else if (e.c == KEY_EDIT) 00970 r = gui->kp_edit; 00971 if (r) { 00972 r->x = atoi(s2); 00973 r->y = e.x0; 00974 r->w = e.y0; 00975 r->h = e.x1; 00976 break; 00977 } 00978 if (strcasecmp(s2, "circle")) /* invalid */ 00979 break; 00980 /* token circle xc yc diameter */ 00981 e.h = e.x1; 00982 e.y1 = e.y0; /* map radius in x1 y1 */ 00983 e.x1 = e.x0 + e.h; /* map radius in x1 y1 */ 00984 e.x0 = e.x0 - e.h; /* map radius in x1 y1 */ 00985 /* fallthrough */ 00986 00987 case 7: 00988 if (e.c == KEY_FONT) { /* font - x0 y0 w h rows cols */ 00989 ast_log(LOG_WARNING, "font not supported yet\n"); 00990 break; 00991 } 00992 /* token circle|rect x0 y0 x1 y1 h */ 00993 if (e.x1 < e.x0 || e.h <= 0) { 00994 ast_log(LOG_WARNING, "error in coordinates\n"); 00995 e.type = 0; 00996 break; 00997 } 00998 if (!strcasecmp(s2, "circle")) { 00999 /* for a circle we specify the diameter but store center and radii */ 01000 e.type = KP_CIRCLE; 01001 e.x0 = (e.x1 + e.x0) / 2; 01002 e.y0 = (e.y1 + e.y0) / 2; 01003 e.h = e.h / 2; 01004 } else if (!strcasecmp(s2, "rect")) { 01005 e.type = KP_RECT; 01006 } else 01007 break; 01008 ret = 1; 01009 } 01010 // ast_log(LOG_WARNING, "reading [%s] returns %d %d\n", val, i, ret); 01011 if (ret == 0) 01012 return 0; 01013 if (gui->kp_size == 0) { 01014 gui->kp = ast_calloc(10, sizeof(e)); 01015 if (gui->kp == NULL) { 01016 ast_log(LOG_WARNING, "cannot allocate kp"); 01017 return 0; 01018 } 01019 gui->kp_size = 10; 01020 } 01021 if (gui->kp_size == gui->kp_used) { /* must allocate */ 01022 struct keypad_entry *a = ast_realloc(gui->kp, sizeof(e)*(gui->kp_size+10)); 01023 if (a == NULL) { 01024 ast_log(LOG_WARNING, "cannot reallocate kp"); 01025 return 0; 01026 } 01027 gui->kp = a; 01028 gui->kp_size += 10; 01029 } 01030 if (gui->kp_size == gui->kp_used) 01031 return 0; 01032 gui->kp[gui->kp_used++] = e; 01033 // ast_log(LOG_WARNING, "now %d regions\n", gui->kp_used); 01034 return 1; 01035 }
static void keypad_digit | ( | struct video_desc * | env, | |
int | digit | |||
) | [static] |
Definition at line 247 of file console_gui.c.
References AST_FRAME_DTMF, ast_queue_frame(), buf, f, and print_message().
00248 { 00249 if (env->owner) { /* we have a call, send the digit */ 00250 struct ast_frame f = { AST_FRAME_DTMF, 0 }; 00251 00252 f.subclass = digit; 00253 ast_queue_frame(env->owner, &f); 00254 } else { /* no call, accumulate digits */ 00255 char buf[2] = { digit, '\0' }; 00256 if (env->gui->bd_msg) /* XXX not strictly necessary ... */ 00257 print_message(env->gui->bd_msg, buf); 00258 } 00259 }
static void keypad_pick_up | ( | struct video_desc * | env | ) | [static] |
Definition at line 297 of file console_gui.c.
References ast_cli_command(), ast_log(), ast_skip_blanks(), gui_info::bd_dialed, gui_info::bd_msg, buf, LOG_WARNING, gui_info::outfd, print_message(), read_message(), and reset_board().
Referenced by handle_keyboard_input().
00298 { 00299 struct gui_info *gui = env->gui; 00300 00301 ast_log(LOG_WARNING, "keypad_pick_up called\n"); 00302 00303 if (env->owner) { /* someone is calling us, just answer */ 00304 ast_cli_command(gui->outfd, "console answer"); 00305 } else { /* we have someone to call */ 00306 char buf[160]; 00307 const char *who = ast_skip_blanks(read_message(gui->bd_msg)); 00308 buf[sizeof(buf) - 1] = '\0'; 00309 snprintf(buf, sizeof(buf), "console dial %s", who); 00310 ast_log(LOG_WARNING, "doing <%s>\n", buf); 00311 print_message(gui->bd_dialed, "\n"); 00312 print_message(gui->bd_dialed, who); 00313 reset_board(gui->bd_msg); 00314 ast_cli_command(gui->outfd, buf); 00315 } 00316 }
static void keypad_setup | ( | struct gui_info * | gui, | |
const char * | kp_file | |||
) | [static] |
Definition at line 687 of file console_gui.c.
References ast_log(), ast_skip_blanks(), ast_trim_blanks(), buf, gui_info::keypad, keypad_cfg_read(), load_image(), LOG_WARNING, and s.
Referenced by gui_init().
00688 { 00689 FILE *fd; 00690 char buf[1024]; 00691 const char region[] = "region"; 00692 int reg_len = strlen(region); 00693 int in_comment = 0; 00694 00695 if (gui->keypad) 00696 return; 00697 gui->keypad = load_image(kp_file); 00698 if (!gui->keypad) 00699 return; 00700 /* now try to read the keymap from the file. */ 00701 fd = fopen(kp_file, "r"); 00702 if (fd == NULL) { 00703 ast_log(LOG_WARNING, "fail to open %s\n", kp_file); 00704 return; 00705 } 00706 /* 00707 * If the keypad image has a comment field, try to read 00708 * the button location from there. The block must start with 00709 * a comment (or empty) line, and continue with entries like: 00710 * region = token shape x0 y0 x1 y1 h 00711 * ... 00712 * (basically, lines have the same format as config file entries). 00713 * You can add it to a jpeg file using wrjpgcom 00714 */ 00715 while (fgets(buf, sizeof(buf), fd)) { 00716 char *s; 00717 00718 if (!strstr(buf, region)) { /* no keyword yet */ 00719 if (!in_comment) /* still waiting for initial comment block */ 00720 continue; 00721 else 00722 break; 00723 } 00724 if (!in_comment) { /* first keyword, reset previous entries */ 00725 keypad_cfg_read(gui, "reset"); 00726 in_comment = 1; 00727 } 00728 s = ast_skip_blanks(buf); 00729 ast_trim_blanks(s); 00730 if (memcmp(s, region, reg_len)) 00731 break; /* keyword not found */ 00732 s = ast_skip_blanks(s + reg_len); /* space between token and '=' */ 00733 if (*s++ != '=') /* missing separator */ 00734 break; 00735 if (*s == '>') /* skip '>' if present */ 00736 s++; 00737 keypad_cfg_read(gui, ast_skip_blanks(s)); 00738 } 00739 fclose(fd); 00740 }
static char* keypad_toggle | ( | struct video_desc * | env, | |
int | index | |||
) | [static] |
Definition at line 262 of file console_gui.c.
References ast_log(), chan_oss_pvt::autoanswer, find_desc(), KEY_AUTOANSWER, KEY_MUTE, KEY_SENDVIDEO, LOG_WARNING, chan_oss_pvt::mute, and oss_active.
00263 { 00264 ast_log(LOG_WARNING, "keypad_toggle(%i) called\n", index); 00265 00266 switch (index) { 00267 case KEY_SENDVIDEO: 00268 env->out.sendvideo = !env->out.sendvideo; 00269 break; 00270 #ifdef notyet 00271 case KEY_MUTE: { 00272 struct chan_oss_pvt *o = find_desc(oss_active); 00273 o->mute = !o->mute; 00274 } 00275 break; 00276 case KEY_AUTOANSWER: { 00277 struct chan_oss_pvt *o = find_desc(oss_active); 00278 o->autoanswer = !o->autoanswer; 00279 } 00280 break; 00281 #endif 00282 } 00283 return NULL; 00284 }
static int kp_match_area | ( | const struct keypad_entry * | e, | |
int | x, | |||
int | y | |||
) | [static] |
Definition at line 865 of file console_gui.c.
References ast_log(), keypad_entry::c, keypad_entry::h, KP_CIRCLE, KP_RECT, LOG_WARNING, keypad_entry::type, keypad_entry::x0, keypad_entry::x1, keypad_entry::y0, and keypad_entry::y1.
Referenced by handle_mousedown().
00866 { 00867 double xp, dx = (e->x1 - e->x0); 00868 double yp, dy = (e->y1 - e->y0); 00869 double l = sqrt(dx*dx + dy*dy); 00870 int ret = 0; 00871 00872 if (l > 1) { /* large enough */ 00873 xp = ((x - e->x0)*dx + (y - e->y0)*dy)/l; 00874 yp = (-(x - e->x0)*dy + (y - e->y0)*dx)/l; 00875 if (e->type == KP_RECT) { 00876 ret = (xp >= 0 && xp < l && yp >=0 && yp < l); 00877 } else if (e->type == KP_CIRCLE) { 00878 dx = xp*xp/(l*l) + yp*yp/(e->h*e->h); 00879 ret = (dx < 1); 00880 } 00881 } 00882 #if 0 00883 ast_log(LOG_WARNING, "result %d [%d] for match %d,%d in type %d p0 %d,%d p1 %d,%d h %d\n", 00884 ret, e->c, x, y, e->type, e->x0, e->y0, e->x1, e->y1, e->h); 00885 #endif 00886 return ret; 00887 }
static SDL_Surface* load_image | ( | const char * | file | ) | [static] |
Definition at line 603 of file console_gui.c.
Referenced by gui_init(), and keypad_setup().
00604 { 00605 SDL_Surface *temp; 00606 00607 #ifdef HAVE_SDL_IMAGE 00608 temp = IMG_Load(file); 00609 #else 00610 temp = SDL_LoadBMP(file); 00611 #endif 00612 if (temp == NULL) 00613 fprintf(stderr, "Unable to load image %s: %s\n", 00614 file, SDL_GetError()); 00615 return temp; 00616 }
static char map_key | ( | SDL_keysym * | ks | ) | [static] |
Definition at line 465 of file console_gui.c.
References s.
Referenced by handle_keyboard_input().
00466 { 00467 const char *s, **p = us_kbd_map; 00468 int c = ks->sym; 00469 00470 if (c == '\r') /* map cr into lf */ 00471 c = '\n'; 00472 if (c >= SDLK_NUMLOCK && c <= SDLK_COMPOSE) 00473 return 0; /* only a modifier */ 00474 if (ks->mod == 0) 00475 return c; 00476 while ((s = *p) && s[0] != c) 00477 p++; 00478 if (s) { /* see if we have a modifier and a chance to use it */ 00479 int l = strlen(s), mod = 0; 00480 if (l > 1) 00481 mod |= (ks->mod & KMOD_SHIFT) ? 1 : 0; 00482 if (l > 2 + mod) 00483 mod |= (ks->mod & KMOD_CTRL) ? 2 : 0; 00484 if (l > 4 + mod) 00485 mod |= (ks->mod & KMOD_ALT) ? 4 : 0; 00486 c = s[mod]; 00487 } 00488 if (ks->mod & (KMOD_CAPS|KMOD_SHIFT) && c >= 'a' && c <='z') 00489 c += 'A' - 'a'; 00490 return c; 00491 }
static void sdl_setup | ( | struct video_desc * | env | ) | [static] |
[re]set the main sdl window, useful in case of resize. We can tell the first from subsequent calls from the value of env->gui, which is NULL the first time.
Definition at line 764 of file console_gui.c.
References ast_log(), gui_info::bd_dialed, gui_info::bd_msg, BORDER, cleanup_sdl(), gui_init(), init_board(), gui_info::keypad, gui_info::kp_dialed, gui_info::kp_msg, gui_info::kp_rect, LOG_ERROR, LOG_WARNING, MAX, display_window::rect, gui_info::screen, set_win(), gui_info::win, WIN_KEYPAD, WIN_LOCAL, and WIN_REMOTE.
00765 { 00766 int dpy_fmt = SDL_IYUV_OVERLAY; /* YV12 causes flicker in SDL */ 00767 int depth, maxw, maxh; 00768 const SDL_VideoInfo *info; 00769 int kp_w = 0, kp_h = 0; /* keypad width and height */ 00770 struct gui_info *gui = env->gui; 00771 00772 /* 00773 * initialize the SDL environment. We have one large window 00774 * with local and remote video, and a keypad. 00775 * At the moment we arrange them statically, as follows: 00776 * - on the left, the remote video; 00777 * - on the center, the keypad 00778 * - on the right, the local video 00779 * We need to read in the skin for the keypad before creating the main 00780 * SDL window, because the size is only known here. 00781 */ 00782 00783 if (gui == NULL && SDL_Init(SDL_INIT_VIDEO)) { 00784 ast_log(LOG_WARNING, "Could not initialize SDL - %s\n", 00785 SDL_GetError()); 00786 /* again not fatal, just we won't display anything */ 00787 return; 00788 } 00789 info = SDL_GetVideoInfo(); 00790 /* We want at least 16bpp to support YUV overlays. 00791 * E.g with SDL_VIDEODRIVER = aalib the default is 8 00792 */ 00793 depth = info->vfmt->BitsPerPixel; 00794 if (depth < 16) 00795 depth = 16; 00796 if (!gui) 00797 env->gui = gui = gui_init(env->keypad_file, env->keypad_font); 00798 if (!gui) 00799 goto no_sdl; 00800 00801 if (gui->keypad) { 00802 if (gui->kp_rect.w > 0 && gui->kp_rect.h > 0) { 00803 kp_w = gui->kp_rect.w; 00804 kp_h = gui->kp_rect.h; 00805 } else { 00806 kp_w = gui->keypad->w; 00807 kp_h = gui->keypad->h; 00808 } 00809 } 00810 /* XXX same for other boards */ 00811 #define BORDER 5 /* border around our windows */ 00812 maxw = env->rem_dpy.w + env->loc_dpy.w + kp_w; 00813 maxh = MAX( MAX(env->rem_dpy.h, env->loc_dpy.h), kp_h); 00814 maxw += 4 * BORDER; 00815 maxh += 2 * BORDER; 00816 gui->screen = SDL_SetVideoMode(maxw, maxh, depth, 0); 00817 if (!gui->screen) { 00818 ast_log(LOG_ERROR, "SDL: could not set video mode - exiting\n"); 00819 goto no_sdl; 00820 } 00821 00822 SDL_WM_SetCaption("Asterisk console Video Output", NULL); 00823 if (set_win(gui->screen, &gui->win[WIN_REMOTE], dpy_fmt, 00824 env->rem_dpy.w, env->rem_dpy.h, BORDER, BORDER)) 00825 goto no_sdl; 00826 if (set_win(gui->screen, &gui->win[WIN_LOCAL], dpy_fmt, 00827 env->loc_dpy.w, env->loc_dpy.h, 00828 3*BORDER+env->rem_dpy.w + kp_w, BORDER)) 00829 goto no_sdl; 00830 00831 /* display the skin, but do not free it as we need it later to 00832 * restore text areas and maybe sliders too. 00833 */ 00834 if (gui->keypad) { 00835 struct SDL_Rect *dest = &gui->win[WIN_KEYPAD].rect; 00836 struct SDL_Rect *src = (gui->kp_rect.w > 0 && gui->kp_rect.h > 0) ? & gui->kp_rect : NULL; 00837 /* set the coordinates of the keypad relative to the main screen */ 00838 dest->x = 2*BORDER + env->rem_dpy.w; 00839 dest->y = BORDER; 00840 dest->w = kp_w; 00841 dest->h = kp_h; 00842 SDL_BlitSurface(gui->keypad, src, gui->screen, dest); 00843 init_board(gui, &gui->bd_msg, gui->kp_msg, dest->x, dest->y); 00844 init_board(gui, &gui->bd_dialed, gui->kp_dialed, dest->x, dest->y); 00845 SDL_UpdateRects(gui->screen, 1, dest); 00846 } 00847 return; 00848 00849 no_sdl: 00850 /* free resources in case of errors */ 00851 env->gui = cleanup_sdl(gui); 00852 }
static void set_drag | ( | struct drag_info * | drag, | |
int | x, | |||
int | y, | |||
enum drag_window | win | |||
) | [static] |
Definition at line 347 of file console_gui.c.
References gui_info::drag, drag_info::drag_window, drag_info::x_start, and drag_info::y_start.
00348 { 00349 drag->x_start = x; 00350 drag->y_start = y; 00351 drag->drag_window = win; 00352 }
static int set_win | ( | SDL_Surface * | screen, | |
struct display_window * | win, | |||
int | fmt, | |||
int | w, | |||
int | h, | |||
int | x, | |||
int | y | |||
) | [static] |
Definition at line 672 of file console_gui.c.
References display_window::bmp, display_window::rect, and gui_info::win.
Referenced by sdl_setup().
00674 { 00675 win->bmp = SDL_CreateYUVOverlay(w, h, fmt, screen); 00676 if (win->bmp == NULL) 00677 return -1; /* error */ 00678 win->rect.x = x; 00679 win->rect.y = y; 00680 win->rect.w = w; 00681 win->rect.h = h; 00682 return 0; 00683 }
static void show_frame | ( | struct video_desc * | env, | |
int | out | |||
) | [static] |
Definition at line 154 of file console_gui.c.
References display_window::bmp, fbuf_t::h, fbuf_t::pix_fmt, display_window::rect, fbuf_t::w, gui_info::win, and WIN_LOCAL.
00155 { 00156 AVPicture *p_in, p_out; 00157 struct fbuf_t *b_in, *b_out; 00158 SDL_Overlay *bmp; 00159 struct gui_info *gui = env->gui; 00160 00161 if (!gui) 00162 return; 00163 00164 if (out == WIN_LOCAL) { /* webcam/x11 to sdl */ 00165 b_in = &env->enc_in; 00166 b_out = &env->loc_dpy; 00167 p_in = NULL; 00168 } else { 00169 /* copy input format from the decoding context */ 00170 AVCodecContext *c; 00171 if (env->in == NULL) /* XXX should not happen - decoder not ready */ 00172 return; 00173 c = env->in->dec_ctx; 00174 b_in = &env->in->dec_out; 00175 b_in->pix_fmt = c->pix_fmt; 00176 b_in->w = c->width; 00177 b_in->h = c->height; 00178 00179 b_out = &env->rem_dpy; 00180 p_in = (AVPicture *)env->in->d_frame; 00181 } 00182 bmp = gui->win[out].bmp; 00183 SDL_LockYUVOverlay(bmp); 00184 /* output picture info - this is sdl, YUV420P */ 00185 memset(&p_out, '\0', sizeof(p_out)); 00186 p_out.data[0] = bmp->pixels[0]; 00187 p_out.data[1] = bmp->pixels[1]; 00188 p_out.data[2] = bmp->pixels[2]; 00189 p_out.linesize[0] = bmp->pitches[0]; 00190 p_out.linesize[1] = bmp->pitches[1]; 00191 p_out.linesize[2] = bmp->pitches[2]; 00192 00193 my_scale(b_in, p_in, b_out, &p_out); 00194 00195 /* lock to protect access to Xlib by different threads. */ 00196 SDL_DisplayYUVOverlay(bmp, &gui->win[out].rect); 00197 SDL_UnlockYUVOverlay(bmp); 00198 }
static int video_geom | ( | struct fbuf_t * | b, | |
const char * | s | |||
) | [static] |
struct _s_k gui_key_map[] [static] |
const char* us_kbd_map[] [static] |
Definition at line 457 of file console_gui.c.