86 #include "console_video.h"
93 enum { WIN_LOCAL, WIN_REMOTE, WIN_KEYPAD, WIN_SRC1,
94 WIN_SRC2, WIN_SRC3, WIN_SRC4, WIN_SRC5,
95 WIN_SRC6, WIN_SRC7, WIN_SRC8, WIN_SRC9, WIN_MAX };
98 static void show_frame(
struct video_desc *
env,
int out) {}
99 static void sdl_setup(
struct video_desc *
env) {}
100 static struct gui_info *cleanup_sdl(
struct gui_info* g,
int n) {
return NULL; }
101 static void eventhandler(
struct video_desc *
env,
const char *caption) {}
102 static int keypad_cfg_read(
struct gui_info *gui,
const char *
val) {
return 0; }
107 #include <SDL/SDL_syswm.h>
108 #ifdef HAVE_SDL_IMAGE
109 #include <SDL/SDL_image.h>
114 #include <X11/Xlib.h>
118 #define SRC_MSG_BD_H 20
120 enum kp_type { KP_NONE, KP_RECT, KP_CIRCLE };
123 int x0, y0, x1, y1, h;
143 enum kb_output kb_output;
152 SDL_Rect font_rects[96];
161 struct board *bd_msg;
164 struct board *bd_edit;
166 SDL_Rect kp_dialed[2];
167 struct board *bd_dialed;
173 struct thumb_bd thumb_bd_array[MAX_VIDEO_SOURCES];
176 int kp_size, kp_used;
194 SDL_FreeSurface(gui->font);
201 SDL_FreeSurface(gui->keypad);
207 for (i = 0; i < WIN_MAX; i++) {
209 SDL_FreeYUVOverlay(gui->win[i].bmp);
211 memset(gui,
'\0',
sizeof(gui));
215 delete_board(gui->bd_dialed);
217 delete_board(gui->bd_msg);
220 for (i = 0; i < device_num; i++) {
221 if (gui->thumb_bd_array[i].board)
222 delete_board(gui->thumb_bd_array[i].board);
236 #define IS_SECONDARY 2
259 static void show_frame(
struct video_desc *
env,
int out)
261 AVPicture *p_in, p_out;
262 struct fbuf_t *b_in, *b_out;
269 if (out == WIN_LOCAL) {
271 b_out = &env->loc_dpy;
273 }
else if (out == WIN_REMOTE) {
278 c = env->in->dec_ctx;
279 b_in = &env->in->dec_out;
280 b_in->pix_fmt = c->pix_fmt;
284 b_out = &env->rem_dpy;
285 p_in = (AVPicture *)env->in->d_frame;
287 int i = out-WIN_SRC1;
288 b_in = env->out.devices[i].dev_buf;
292 b_out = &env->src_dpy[i];
294 bmp = gui->win[out].bmp;
295 SDL_LockYUVOverlay(bmp);
297 memset(&p_out,
'\0',
sizeof(p_out));
298 p_out.data[0] = bmp->pixels[0];
299 p_out.data[1] = bmp->pixels[1];
300 p_out.data[2] = bmp->pixels[2];
301 p_out.linesize[0] = bmp->pitches[0];
302 p_out.linesize[1] = bmp->pitches[1];
303 p_out.linesize[2] = bmp->pitches[2];
305 my_scale(b_in, p_in, b_out, &p_out);
308 SDL_DisplayYUVOverlay(bmp, &gui->win[out].rect);
309 SDL_UnlockYUVOverlay(bmp);
324 KEY_AUTOANSWER = 131,
326 KEY_LOCALVIDEO = 133,
327 KEY_REMOTEVIDEO = 134,
331 KEY_MESSAGEBOARD = 140,
332 KEY_DIALEDBOARD = 141,
346 KEY_AUDIO_SRCS = 210,
361 KEY_OUT_OF_KEYPAD = 241,
366 KEY_DIGIT_BACKGROUND = 255,
374 static void keypad_digit(
struct video_desc *env,
int digit)
377 struct ast_frame f = { AST_FRAME_DTMF, 0 };
382 char buf[2] = { digit,
'\0' };
383 if (env->gui->bd_msg)
384 print_message(env->gui->bd_msg, buf);
389 static char *keypad_toggle(
struct video_desc *env,
int index)
391 ast_log(LOG_WARNING,
"keypad_toggle(%i) called\n", index);
395 env->out.sendvideo = !env->out.sendvideo;
399 env->out.picture_in_picture = !env->out.picture_in_picture;
407 env->frame_freeze = !env->frame_freeze;
411 case KEY_AUTOANSWER: {
412 struct chan_oss_pvt *o = find_desc(oss_active);
413 o->autoanswer = !o->autoanswer;
421 char *console_do_answer(
int fd);
432 static void keypad_pick_up(
struct video_desc *env)
436 ast_log(LOG_WARNING,
"keypad_pick_up called\n");
443 buf[
sizeof(buf) - 1] =
'\0';
444 snprintf(buf,
sizeof(buf),
"console dial %s", who);
445 ast_log(LOG_WARNING,
"doing <%s>\n", buf);
446 print_message(gui->bd_dialed,
"\n");
447 print_message(gui->bd_dialed, who);
448 reset_board(gui->bd_msg);
472 static int gui_output(
struct video_desc *env,
const char *text)
478 static int video_geom(
struct fbuf_t *b,
const char *s);
479 static void sdl_setup(
struct video_desc *env);
480 static int kp_match_area(
const struct keypad_entry *e,
int x,
int y);
482 static void set_drag(
struct drag_info *drag,
int x,
int y,
enum drag_window win)
486 drag->drag_window = win;
489 static int update_device_info(
struct video_desc *env,
int i)
491 reset_board(env->gui->thumb_bd_array[i].board);
492 print_message(env->gui->thumb_bd_array[i].board,
493 src_msgs[env->out.devices[i].status_index]);
516 static int switch_video_out(
struct video_desc *env,
int index, Uint8 button)
520 if (index >= env->out.device_num) {
521 ast_log(LOG_WARNING,
"no devices\n");
525 p = (button == SDL_BUTTON_LEFT) ? &env->out.device_primary :
526 &env->out.device_secondary;
529 ast_log(LOG_WARNING,
"device %s already selected\n", env->out.devices[index].name);
532 ast_log(LOG_WARNING,
"switching to %s...\n", env->out.devices[index].name);
534 if (env->out.devices[index].grabber) {
538 if (p == &env->out.device_primary)
539 env->out.devices[*p].status_index &= ~IS_PRIMARY;
541 env->out.devices[*p].status_index &= ~IS_SECONDARY;
542 update_device_info(env, *p);
545 ast_log(LOG_WARNING,
"done\n");
547 if (p == &env->out.device_primary)
548 env->out.devices[*p].status_index |= IS_PRIMARY;
550 env->out.devices[*p].status_index |= IS_SECONDARY;
551 update_device_info(env, *p);
555 ast_log(LOG_WARNING,
"device is down\n");
570 static int turn_on_off(
int index,
struct video_desc *env)
572 struct video_device *p = &env->out.devices[index];
574 if (index >= env->out.device_num) {
575 ast_log(LOG_WARNING,
"no devices\n");
585 for (i = 0; (g = console_grabbers[i]); i++) {
587 g_data = g->open(p->name, &env->out.loc_src_geometry, env->out.fps);
591 p->grabber_data = g_data;
593 p->status_index |= IS_ON;
595 update_device_info(env, index);
601 p->grabber_data = p->grabber->close(p->grabber_data);
606 p->status_index &= ~IS_ON;
608 update_device_info(env, index);
619 static void handle_mousedown(
struct video_desc *env, SDL_MouseButtonEvent button)
621 uint8_t index = KEY_OUT_OF_KEYPAD;
629 int src_wins_tot_w = env->out.device_num*(SRC_WIN_W+BORDER)+BORDER;
632 int x0 = MAX(env->rem_dpy.w+gui->keypad->w/2+2*BORDER, src_wins_tot_w/2);
635 ast_log(LOG_WARNING,
"event %d %d have %d/%d regions at %p\n",
636 button.x, button.y, gui->kp_used, gui->kp_size, gui->kp);
639 gui->drag.drag_window = DRAG_NONE;
643 if (button.y >= (env->out.device_num ? SRC_WIN_H+2*BORDER+SRC_MSG_BD_H : 0)) {
647 button.y -= (env->out.device_num ? SRC_WIN_H+2*BORDER+SRC_MSG_BD_H : 0);
648 if (button.y < BORDER)
649 index = KEY_OUT_OF_KEYPAD;
650 else if (button.y >= MAX(MAX(env->rem_dpy.h, env->loc_dpy.h), gui->keypad->h))
651 index = KEY_OUT_OF_KEYPAD;
652 else if (button.x < x0 - gui->keypad->w/2 - BORDER - env->rem_dpy.w)
653 index = KEY_OUT_OF_KEYPAD;
654 else if (button.x < x0 - gui->keypad->w/2 - BORDER)
656 else if (button.x < x0 - gui->keypad->w/2)
657 index = KEY_OUT_OF_KEYPAD;
658 else if (button.x >= x0 + gui->keypad->w/2 + BORDER + env->loc_dpy.w)
659 index = KEY_OUT_OF_KEYPAD;
660 else if (button.x >= x0 + gui->keypad->w/2 + BORDER)
662 else if (button.x >= x0 + gui->keypad->w/2)
663 index = KEY_OUT_OF_KEYPAD;
667 int x_keypad = button.x - (x0 - gui->keypad->w/2);
669 for (i = 0; i < gui->kp_used; i++) {
670 if (kp_match_area(&gui->kp[i],x_keypad, button.y - BORDER)) {
671 index = gui->kp[i].c;
676 }
else if (button.y < BORDER) {
677 index = KEY_OUT_OF_KEYPAD;
679 x = x0 - src_wins_tot_w/2 + BORDER;
680 if (button.y >= BORDER + SRC_WIN_H)
681 index = KEY_OUT_OF_KEYPAD;
682 else if (button.x < x)
683 index = KEY_OUT_OF_KEYPAD;
684 else if (button.x < x + src_wins_tot_w - BORDER) {
689 for (i = 1; i <= env->out.device_num; i++) {
690 if (button.x < x+i*(SRC_WIN_W+BORDER)-BORDER) {
691 index = KEY_SRCS_WIN+i-1;
693 }
else if (button.x < x+i*(SRC_WIN_W+BORDER)) {
694 index = KEY_OUT_OF_KEYPAD;
699 index = KEY_OUT_OF_KEYPAD;
704 keypad_digit(env, index);
708 else if (index >= KEY_SRCS_WIN && index < KEY_SRCS_WIN+env->out.device_num) {
709 index -= KEY_SRCS_WIN;
712 if (button.button == SDL_BUTTON_RIGHT || button.button == SDL_BUTTON_LEFT) {
713 switch_video_out(env, index, button.button);
718 int ret = turn_on_off(index, env);
721 ast_log(LOG_WARNING,
"unable to turn on device %s\n",
722 env->out.devices[index].name);
724 ast_log(LOG_WARNING,
"device %s changed state to on\n",
725 env->out.devices[index].name);
727 ast_log(LOG_WARNING,
"device %s changed state to off\n",
728 env->out.devices[index].name);
753 keypad_toggle(env, index);
758 case KEY_REMOTEVIDEO:
766 case KEY_MESSAGEBOARD:
767 if (button.button == SDL_BUTTON_LEFT)
768 set_drag(&gui->drag, button.x, button.y, DRAG_MESSAGE);
774 if (button.button == SDL_BUTTON_LEFT) {
776 int pip_loc_x = (double)env->out.pip_x/env->enc_in.w * env->loc_dpy.w;
777 int pip_loc_y = (
double)env->out.pip_y/env->enc_in.h * env->loc_dpy.h;
779 if (index == KEY_LOC_DPY && env->out.picture_in_picture &&
780 button.x >= x0+gui->keypad->w/2+BORDER+pip_loc_x &&
781 button.x < x0+gui->keypad->w/2+BORDER+pip_loc_x+env->loc_dpy.w/3 &&
782 button.y >= BORDER+pip_loc_y &&
783 button.y < BORDER+pip_loc_y+env->loc_dpy.h/3) {
785 button.y += (env->out.device_num ? SRC_WIN_H+2*BORDER+SRC_MSG_BD_H : 0);
787 set_drag(&gui->drag, button.x, button.y, DRAG_PIP);
789 else if (index == KEY_LOC_DPY) {
791 button.y += (env->out.device_num ? SRC_WIN_H+2*BORDER+SRC_MSG_BD_H : 0);
793 set_drag(&gui->drag, button.x, button.y, DRAG_LOCAL);
798 struct fbuf_t *fb = index == KEY_LOC_DPY ? &env->loc_dpy : &env->rem_dpy;
799 sprintf(buf,
"%c%dx%d", button.button == SDL_BUTTON_RIGHT ?
'>' :
'<',
807 for (i = 0; i < env->out.device_num; i++) {
808 update_device_info(env, i);
812 print_message(gui->bd_msg,
" \b");
813 print_message(gui->bd_dialed,
" \b");
816 case KEY_OUT_OF_KEYPAD:
817 ast_log(LOG_WARNING,
"nothing clicked, coordinates: %d, %d\n", button.x, button.y);
820 case KEY_DIGIT_BACKGROUND:
824 ast_log(LOG_WARNING,
"function not yet defined %i\n", index);
839 static const char *
const us_kbd_map[] = {
840 "`~",
"1!",
"2@",
"3#",
"4$",
"5%",
"6^",
841 "7&",
"8*",
"9(",
"0)",
"-_",
"=+",
"[{",
842 "]}",
"\\|",
";:",
"'\"",
",<",
".>",
"/?",
847 static char map_key(SDL_keysym *ks)
849 const char *s, **p = us_kbd_map;
854 if (c >= SDLK_NUMLOCK && c <= SDLK_COMPOSE)
858 while ((s = *p) && s[0] != c)
861 int l = strlen(s), mod = 0;
863 mod |= (ks->mod & KMOD_SHIFT) ? 1 : 0;
865 mod |= (ks->mod & KMOD_CTRL) ? 2 : 0;
867 mod |= (ks->mod & KMOD_ALT) ? 4 : 0;
870 if (ks->mod & (KMOD_CAPS|KMOD_SHIFT) && c >=
'a' && c <=
'z')
875 static void handle_keyboard_input(
struct video_desc *env, SDL_keysym *ks)
877 char buf[2] = { map_key(ks),
'\0' };
881 switch (gui->kb_output) {
888 print_message(gui->bd_msg, buf);
889 if (buf[0] ==
'\r' || buf[0] ==
'\n') {
902 static void grabber_move(
struct video_device *,
int dx,
int dy);
904 int compute_drag(
int *start,
int end,
int magnifier);
905 int compute_drag(
int *start,
int end,
int magnifier)
907 int delta = end - *start;
910 delta += delta * delta * (delta > 0 ? 1 : -1 )/100;
911 delta *= POLARITY * magnifier;
925 static void pip_move(
struct video_desc* env,
int dx,
int dy) {
926 int new_pip_x = env->out.pip_x+dx;
927 int new_pip_y = env->out.pip_y+dy;
932 else if (new_pip_x > env->enc_in.w - env->enc_in.w/3)
933 new_pip_x = env->enc_in.w - env->enc_in.w/3;
938 else if (new_pip_y > env->enc_in.h - env->enc_in.h/3)
939 new_pip_y = env->enc_in.h - env->enc_in.h/3;
940 env->out.pip_x = new_pip_x;
941 env->out.pip_y = new_pip_y;
953 static void eventhandler(
struct video_desc *env,
const char *caption)
959 SDL_Event ev[N_EVENTS];
965 SDL_WM_SetCaption(caption, NULL);
967 #define MY_EV (SDL_MOUSEBUTTONDOWN|SDL_KEYDOWN)
968 while ( (n = SDL_PeepEvents(ev, N_EVENTS, SDL_GETEVENT, SDL_ALLEVENTS)) > 0) {
969 for (i = 0; i < n; i++) {
971 ast_log(LOG_WARNING,
"------ event %d at %d %d\n",
972 ev[i].type, ev[i].button.x, ev[i].button.y);
974 switch (ev[i].type) {
976 ast_log(LOG_WARNING,
"------ event %d at %d %d\n",
977 ev[i].type, ev[i].button.x, ev[i].button.y);
980 case SDL_ACTIVEEVENT:
982 if (ev[i].active.gain == 0 && ev[i].active.state & SDL_APPACTIVE) {
983 ast_log(LOG_WARNING,
"/* somebody has killed us ? */\n");
993 handle_keyboard_input(env, &ev[i].key.keysym);
996 case SDL_MOUSEMOTION:
997 case SDL_MOUSEBUTTONUP:
998 if (drag->drag_window == DRAG_LOCAL && env->out.device_num) {
1000 int dx = compute_drag(&drag->x_start, ev[i].motion.x, 3);
1001 int dy = compute_drag(&drag->y_start, ev[i].motion.y, 3);
1002 grabber_move(&env->out.devices[env->out.device_primary], dx, dy);
1003 }
else if (drag->drag_window == DRAG_PIP) {
1005 int dx = ev[i].motion.x - drag->x_start;
1006 int dy = ev[i].motion.y - drag->y_start;
1009 dx = (double)dx*env->enc_in.w/env->loc_dpy.w;
1010 dy = (
double)dy*env->enc_in.h/env->loc_dpy.h;
1012 drag->x_start = ev[i].motion.x;
1013 drag->y_start = ev[i].motion.y;
1015 pip_move(env, dx, dy);
1016 }
else if (drag->drag_window == DRAG_MESSAGE) {
1018 int dy = compute_drag(&drag->y_start, ev[i].motion.y, 1);
1019 move_message_board(gui->bd_msg, dy);
1021 if (ev[i].type == SDL_MOUSEBUTTONUP)
1022 drag->drag_window = DRAG_NONE;
1024 case SDL_MOUSEBUTTONDOWN:
1025 handle_mousedown(env, ev[i].button);
1038 fprintf(stderr,
"-------- SDL_PumpEvents took %dms\n", i);
1043 static SDL_Surface *load_image(
const char *file)
1047 #ifdef HAVE_SDL_IMAGE
1048 temp = IMG_Load(file);
1050 temp = SDL_LoadBMP(file);
1053 fprintf(stderr,
"Unable to load image %s: %s\n",
1054 file, SDL_GetError());
1058 static void keypad_setup(
struct gui_info *gui,
const char *kp_file);
1062 static struct gui_info *gui_init(
const char *keypad_file,
const char *font)
1069 gui->kb_output = KO_MESSAGE;
1070 gui->drag.drag_window = DRAG_NONE;
1073 keypad_setup(gui, keypad_file);
1074 if (gui->keypad == NULL)
1077 if (!ast_strlen_zero(font)) {
1081 gui->font = load_image(font);
1083 ast_log(LOG_WARNING,
"Unable to load font %s, no output available\n", font);
1086 ast_log(LOG_WARNING,
"Loaded font %s\n", font);
1088 r = gui->font_rects;
1091 for (i = 0; i < 96; r++, i++) {
1092 r->x = (i % 32 ) * FONT_W;
1093 r->y = (i / 32 ) * FONT_H;
1099 gui->outfd = open (
"/dev/null", O_WRONLY);
1100 if (gui->outfd < 0) {
1101 ast_log(LOG_WARNING,
"Unable output fd\n");
1112 static int set_win(SDL_Surface *screen,
struct display_window *win,
int fmt,
1113 int w,
int h,
int x,
int y)
1115 win->bmp = SDL_CreateYUVOverlay(w, h, fmt, screen);
1116 if (win->bmp == NULL)
1125 static int keypad_cfg_read(
struct gui_info *gui,
const char *
val);
1127 static void keypad_setup(
struct gui_info *gui,
const char *kp_file)
1131 const char region[] =
"region";
1132 int reg_len = strlen(region);
1137 gui->keypad = load_image(kp_file);
1141 fd = fopen(kp_file,
"r");
1143 ast_log(LOG_WARNING,
"fail to open %s\n", kp_file);
1155 while (fgets(buf,
sizeof(buf), fd)) {
1158 if (!strstr(buf, region)) {
1165 keypad_cfg_read(gui,
"reset");
1170 if (memcmp(s, region, reg_len))
1182 struct board *board_setup(SDL_Surface *screen, SDL_Rect *dest,
1183 SDL_Surface *font, SDL_Rect *font_rects);
1186 static void init_board(
struct gui_info *gui,
struct board **dst, SDL_Rect *r,
int dx,
int dy)
1188 if (r[0].w == 0 || r[0].h == 0)
1194 *dst = board_setup(gui->screen, &r[1], gui->font, gui->font_rects);
1208 static int my_x_handler(Display *d, XErrorEvent *e)
1210 ast_log(LOG_WARNING,
"%s error_code %d\n", __FUNCTION__, e->error_code);
1219 static void sdl_setup(
struct video_desc *env)
1221 int dpy_fmt = SDL_IYUV_OVERLAY;
1222 int depth, maxw, maxh;
1223 const SDL_VideoInfo *info;
1224 int kp_w = 0, kp_h = 0;
1236 const char *e = getenv(
"SDL_WINDOWID");
1238 if (!ast_strlen_zero(e)) {
1239 XWindowAttributes a;
1240 int (*old_x_handler)(Display *d, XErrorEvent *e) = XSetErrorHandler(my_x_handler);
1241 Display *d = XOpenDisplay(getenv(
"DISPLAY"));
1243 int success = w ? XGetWindowAttributes(d, w, &a) : 0;
1245 XSetErrorHandler(old_x_handler);
1247 ast_log(LOG_WARNING,
"%s error in window\n", __FUNCTION__);
1265 if (gui == NULL && SDL_Init(SDL_INIT_VIDEO)) {
1266 ast_log(LOG_WARNING,
"Could not initialize SDL - %s\n",
1271 info = SDL_GetVideoInfo();
1275 if (!info || !info->vfmt) {
1276 ast_log(LOG_WARNING,
"Bad SDL_GetVideoInfo - %s\n",
1280 depth = info->vfmt->BitsPerPixel;
1284 env->gui = gui = gui_init(env->keypad_file, env->keypad_font);
1289 if (gui->kp_rect.w > 0 && gui->kp_rect.h > 0) {
1290 kp_w = gui->kp_rect.w;
1291 kp_h = gui->kp_rect.h;
1293 kp_w = gui->keypad->w;
1294 kp_h = gui->keypad->h;
1299 src_wins_tot_w = env->out.device_num*(SRC_WIN_W+BORDER)+BORDER;
1302 x0 = MAX(env->rem_dpy.w+kp_w/2+2*BORDER, src_wins_tot_w/2);
1305 x1 = MAX(env->loc_dpy.w+kp_w/2+2*BORDER, src_wins_tot_w/2);
1311 maxh = MAX( MAX(env->rem_dpy.h, env->loc_dpy.h), kp_h)+2*BORDER;
1312 maxh += env->out.device_num ? (2*BORDER+SRC_WIN_H+SRC_MSG_BD_H) : 0;
1314 gui->screen = SDL_SetVideoMode(maxw, maxh, depth, 0);
1316 ast_log(LOG_ERROR,
"SDL: could not set video mode - exiting\n");
1329 XWindowAttributes attr;
1332 Display *SDL_Display;
1335 const char *e = getenv(
"SDL_WINDOWID");
1336 if (ast_strlen_zero(e))
1338 SDL_VERSION(&info.version);
1339 if (SDL_GetWMInfo(&info) != 1) {
1340 fprintf(stderr,
"no wm info\n");
1343 SDL_Display = info.info.x11.display;
1344 if (SDL_Display == NULL)
1346 win = info.info.x11.window;
1352 want = KeyPressMask | KeyReleaseMask | ButtonPressMask |
1353 ButtonReleaseMask | EnterWindowMask |
1354 LeaveWindowMask | PointerMotionMask |
1356 Button2MotionMask | Button3MotionMask |
1357 Button4MotionMask | Button5MotionMask |
1358 ButtonMotionMask | KeymapStateMask |
1359 ExposureMask | VisibilityChangeMask |
1360 StructureNotifyMask |
1361 SubstructureNotifyMask | SubstructureRedirectMask |
1362 FocusChangeMask | PropertyChangeMask |
1363 ColormapChangeMask | OwnerGrabButtonMask;
1365 memset(&attr,
'\0',
sizeof(attr));
1366 XGetWindowAttributes(SDL_Display, win, &attr);
1374 long ev = ButtonPressMask | ResizeRedirectMask |
1375 SubstructureRedirectMask;
1376 ev &= (attr.all_event_masks & ~attr.your_event_mask);
1382 want |= attr.your_event_mask;
1384 XSelectInput(SDL_Display, win, want);
1392 XResizeWindow(SDL_Display, win, maxw, maxh);
1394 XConfigureEvent ce = {
1395 .type = ConfigureNotify,
1398 .display = SDL_Display,
1407 .override_redirect = 0 };
1408 XSendEvent(SDL_Display, win, 1 , StructureNotifyMask, (XEvent *)&ce);
1413 y0 = env->out.device_num ? (3*BORDER+SRC_WIN_H+SRC_MSG_BD_H) : BORDER;
1415 SDL_WM_SetCaption(
"Asterisk console Video Output", NULL);
1418 if (set_win(gui->screen, &gui->win[WIN_REMOTE], dpy_fmt,
1419 env->rem_dpy.w, env->rem_dpy.h, x0-kp_w/2-BORDER-env->rem_dpy.w, y0))
1422 env->frame_freeze = 0;
1424 if (set_win(gui->screen, &gui->win[WIN_LOCAL], dpy_fmt,
1425 env->loc_dpy.w, env->loc_dpy.h,
1426 x0+kp_w/2+BORDER, y0))
1431 x = x0 - src_wins_tot_w/2 + BORDER;
1432 for (i = 0; i < env->out.device_num; i++){
1433 struct thumb_bd *p = &gui->thumb_bd_array[i];
1434 if (set_win(gui->screen, &gui->win[i+WIN_SRC1], dpy_fmt,
1435 SRC_WIN_W, SRC_WIN_H, x+i*(BORDER+SRC_WIN_W), BORDER))
1438 p->rect.w = SRC_WIN_W;
1439 p->rect.h = SRC_MSG_BD_H;
1440 p->rect.x = x+i*(BORDER+SRC_WIN_W);
1441 p->rect.y = 2*BORDER+SRC_WIN_H;
1443 SDL_FillRect(gui->screen, &p->rect,
1444 SDL_MapRGB(gui->screen->format, 255, 255, 255));
1448 board_setup(gui->screen, &p->rect,
1449 gui->font, gui->font_rects);
1451 SDL_UpdateRect(gui->screen, p->rect.x, p->rect.y, p->rect.w, p->rect.h);
1457 struct SDL_Rect *dest = &gui->win[WIN_KEYPAD].rect;
1458 struct SDL_Rect *src = (gui->kp_rect.w > 0 && gui->kp_rect.h > 0) ? & gui->kp_rect : NULL;
1460 dest->x = x0-kp_w/2;
1464 SDL_BlitSurface(gui->keypad, src, gui->screen, dest);
1465 init_board(gui, &gui->bd_msg, gui->kp_msg, dest->x, dest->y);
1466 init_board(gui, &gui->bd_dialed, gui->kp_dialed, dest->x, dest->y);
1467 SDL_UpdateRects(gui->screen, 1, dest);
1473 env->gui = cleanup_sdl(gui, env->out.device_num);
1487 static int kp_match_area(
const struct keypad_entry *e,
int x,
int y)
1489 double xp, dx = (e->x1 - e->x0);
1490 double yp, dy = (e->y1 - e->y0);
1491 double l = sqrt(dx*dx + dy*dy);
1495 xp = ((x - e->x0)*dx + (y - e->y0)*dy)/l;
1496 yp = (-(x - e->x0)*dy + (y - e->y0)*dx)/l;
1497 if (e->type == KP_RECT) {
1498 ret = (xp >= 0 && xp < l && yp >=0 && yp < e->h);
1499 }
else if (e->type == KP_CIRCLE) {
1500 dx = xp*xp/(l*l) + yp*yp/(e->h*e->h);
1505 ast_log(LOG_WARNING,
"result %d [%d] for match %d,%d in type %d p0 %d,%d p1 %d,%d h %d\n",
1506 ret, e->c, x, y, e->type, e->x0, e->y0, e->x1, e->y1, e->h);
1511 struct _s_k {
const char *s;
int k; };
1512 static const struct _s_k gui_key_map[] = {
1513 {
"FREEZE", KEY_FREEZE},
1515 {
"PICK_UP", KEY_PICK_UP },
1516 {
"PICKUP", KEY_PICK_UP },
1517 {
"HANG_UP", KEY_HANG_UP },
1518 {
"HANGUP", KEY_HANG_UP },
1519 {
"MUTE", KEY_MUTE },
1520 {
"FLASH", KEY_FLASH },
1521 {
"AUTOANSWER", KEY_AUTOANSWER },
1522 {
"SENDVIDEO", KEY_SENDVIDEO },
1523 {
"LOCALVIDEO", KEY_LOCALVIDEO },
1524 {
"REMOTEVIDEO", KEY_REMOTEVIDEO },
1525 {
"GUI_CLOSE", KEY_GUI_CLOSE },
1526 {
"MESSAGEBOARD", KEY_MESSAGEBOARD },
1527 {
"DIALEDBOARD", KEY_DIALEDBOARD },
1528 {
"EDITBOARD", KEY_EDITBOARD },
1529 {
"KEYPAD", KEY_KEYPAD },
1530 {
"MESSAGE", KEY_MESSAGE },
1531 {
"DIALED", KEY_DIALED },
1532 {
"EDIT", KEY_EDIT },
1533 {
"FONT", KEY_FONT },
1536 static int gui_map_token(
const char *s)
1541 if (i > 0 || s[1] ==
'\0')
1542 return (i > 9) ? i : s[0];
1543 for (p = gui_key_map; p->s; p++) {
1544 if (!strcasecmp(p->s, s))
1561 static int keypad_cfg_read(
struct gui_info *gui,
const char *
val)
1565 char s1[16], s2[16];
1568 if (gui == NULL || val == NULL)
1571 s1[0] = s2[0] =
'\0';
1572 memset(&e,
'\0',
sizeof(e));
1573 i = sscanf(val,
"%14s %14s %d %d %d %d %d",
1574 s1, s2, &e.x0, &e.y0, &e.x1, &e.y1, &e.h);
1576 e.c = gui_map_token(s1);
1577 if (e.c == KEY_NONE)
1583 if (e.c != KEY_RESET)
1589 if (e.c == KEY_KEYPAD)
1591 else if (e.c == KEY_MESSAGE)
1593 else if (e.c == KEY_DIALED)
1595 else if (e.c == KEY_EDIT)
1604 if (strcasecmp(s2,
"circle"))
1614 if (e.c == KEY_FONT) {
1615 ast_log(LOG_WARNING,
"font not supported yet\n");
1619 if (e.x1 < e.x0 || e.h <= 0) {
1620 ast_log(LOG_WARNING,
"error in coordinates\n");
1624 if (!strcasecmp(s2,
"circle")) {
1627 e.x0 = (e.x1 + e.x0) / 2;
1628 e.y0 = (e.y1 + e.y0) / 2;
1630 }
else if (!strcasecmp(s2,
"rect")) {
1639 if (gui->kp_size == 0) {
1641 if (gui->kp == NULL) {
1642 ast_log(LOG_WARNING,
"cannot allocate kp\n");
1647 if (gui->kp_size == gui->kp_used) {
1650 ast_log(LOG_WARNING,
"cannot reallocate kp\n");
1656 if (gui->kp_size == gui->kp_used)
1658 gui->kp[gui->kp_used++] = e;
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
#define ast_realloc(p, len)
A wrapper for realloc()
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
struct ast_frame_subclass subclass
Asterisk internal frame definitions.
ast_cli_command
calling arguments for new-style handlers.
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
char * ast_trim_blanks(char *str)
Trims trailing whitespace characters from a string.
#define ast_calloc(num, len)
A wrapper for calloc()
Data structure associated with a single frame of data.