107#include <SDL/SDL_syswm.h> 
  109#include <SDL/SDL_image.h>       
  118#define SRC_MSG_BD_H 20      
  120enum kp_type { KP_NONE, KP_RECT, KP_CIRCLE };
 
  123        int x0, y0, x1, y1, h;  
 
  130struct display_window {
 
  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;
 
  176    int kp_size, kp_used;
 
  177    struct keypad_entry *kp;
 
  179    struct display_window   win[
WIN_MAX];
 
  185static struct gui_info *
cleanup_sdl(
struct gui_info *gui, 
int device_num)
 
  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));
 
  220    for (i = 0; i < device_num; i++) {
 
  221        if (gui->thumb_bd_array[i].board) 
 
  236#define IS_SECONDARY 2 
  261    AVPicture *p_in, p_out;
 
  262    struct fbuf_t *b_in, *b_out;
 
  264    struct gui_info *gui = 
env->gui;
 
  271        b_out = &
env->loc_dpy;
 
  278        c = 
env->in->dec_ctx;
 
  279        b_in = &
env->in->dec_out;
 
  284        b_out = &
env->rem_dpy;
 
  285        p_in = (AVPicture *)
env->in->d_frame;
 
  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, 
 
  374static void keypad_digit(
struct video_desc *
env, 
int digit)
 
  383        if (
env->gui->bd_msg) 
 
  389static char *keypad_toggle(
struct video_desc *
env, 
int 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;
 
  421char *console_do_answer(
int fd);
 
  432static void keypad_pick_up(
struct video_desc *
env)
 
  434    struct gui_info *gui = 
env->gui;
 
  443        buf[
sizeof(
buf) - 1] = 
'\0';
 
  444        snprintf(
buf, 
sizeof(
buf), 
"console dial %s", who);
 
  472static int gui_output(
struct video_desc *
env, 
const char *text)
 
  478static int video_geom(
struct fbuf_t *
b, 
const char *s);
 
  480static int kp_match_area(
const struct keypad_entry *e, 
int x, 
int y);
 
  489static int update_device_info(
struct video_desc *
env, 
int i)
 
  493        src_msgs[
env->out.devices[i].status_index]);
 
  516static int switch_video_out(
struct video_desc *
env, 
int index, Uint8 button)
 
  520    if (index >= 
env->out.device_num) {
 
  525    p = (button == SDL_BUTTON_LEFT) ? &
env->out.device_primary :
 
  526        &
env->
out.device_secondary;
 
  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);
 
  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);
 
  570static 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) {
 
  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);
 
  619static void handle_mousedown(
struct video_desc *
env, SDL_MouseButtonEvent button)
 
  621    uint8_t index = KEY_OUT_OF_KEYPAD;  
 
  622    struct gui_info *gui = 
env->gui;
 
  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);
 
  636        button.x, button.y, gui->kp_used, gui->kp_size, gui->kp);
 
  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;
 
  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);
 
  722                    env->out.devices[index].name);
 
  725                    env->out.devices[index].name);
 
  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)
 
  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);
 
  816    case KEY_OUT_OF_KEYPAD:
 
  820    case KEY_DIGIT_BACKGROUND:
 
  839static const char * 
const us_kbd_map[] = {
 
  840    "`~", 
"1!", 
"2@", 
"3#", 
"4$", 
"5%", 
"6^",
 
  841    "7&", 
"8*", 
"9(", 
"0)", 
"-_", 
"=+", 
"[{",
 
  842    "]}", 
"\\|", 
";:", 
"'\"", 
",<", 
".>", 
"/?",
 
  847static 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')
 
  875static void handle_keyboard_input(
struct video_desc *
env, SDL_keysym *ks)
 
  877    char buf[2] = { map_key(ks), 
'\0' };
 
  878    struct gui_info *gui = 
env->gui;
 
  881    switch (gui->kb_output) {
 
  889            if (
buf[0] == 
'\r' || 
buf[0] == 
'\n') {
 
  902static void grabber_move(
struct video_device *, 
int dx, 
int dy);
 
  904int compute_drag(
int *start, 
int end, 
int magnifier);
 
  905int 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;
 
  925static 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;
 
  955    struct gui_info *gui = 
env->gui;
 
  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++) {
 
  972                ev[i].
type,  ev[i].button.x,  ev[i].button.y);
 
  974            switch (ev[i].
type) {
 
  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) {
 
  993                handle_keyboard_input(
env, &ev[i].key.keysym);
 
  996            case SDL_MOUSEMOTION:
 
  997            case SDL_MOUSEBUTTONUP:
 
 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);
 
 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);
 
 1018                    int dy = compute_drag(&drag->
y_start, ev[i].motion.y, 1);
 
 1021                if (ev[i].
type == SDL_MOUSEBUTTONUP)
 
 1024            case SDL_MOUSEBUTTONDOWN:
 
 1025                handle_mousedown(
env, ev[i].button);
 
 1038            fprintf(stderr, 
"-------- SDL_PumpEvents took %dms\n", i);
 
 1043static 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());
 
 1058static void keypad_setup(
struct gui_info *gui, 
const char *kp_file);
 
 1062static struct gui_info *gui_init(
const char *keypad_file, 
const char *font)
 
 1064    struct gui_info *gui = 
ast_calloc(1, 
sizeof(*gui));
 
 1073    keypad_setup(gui, keypad_file);
 
 1074    if (gui->keypad == 
NULL)    
 
 1081        gui->font = load_image(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) {
 
 1112static 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)
 
 1127static 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");
 
 1155    while (fgets(
buf, 
sizeof(
buf), fd)) {
 
 1158        if (!strstr(
buf, region)) { 
 
 1170        if (memcmp(s, region, reg_len))
 
 1182struct board *board_setup(SDL_Surface *screen, SDL_Rect *dest,
 
 1183    SDL_Surface *font, SDL_Rect *font_rects);
 
 1186static 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);
 
 1208static int my_x_handler(Display *
d, XErrorEvent *e)
 
 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; 
 
 1225    struct gui_info *gui = 
env->gui;
 
 1236    const char *e = getenv(
"SDL_WINDOWID");
 
 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);
 
 1265    if (gui == 
NULL && SDL_Init(SDL_INIT_VIDEO)) {
 
 1271    info = SDL_GetVideoInfo();
 
 1275    if (!info || !
info->vfmt) {
 
 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);
 
 1329    XWindowAttributes attr;
 
 1332    Display *SDL_Display;
 
 1335    const char *e = getenv(
"SDL_WINDOWID");
 
 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,
 
 1439        p->rect.h = SRC_MSG_BD_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);
 
 1487static 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);
 
 1511struct _s_k { 
const char *s; 
int k; };
 
 1512static 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 },
 
 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 }, 
 
 1536static 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))
 
 1563    struct keypad_entry e;
 
 1565    char s1[16], s2[16];
 
 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) {  
 
 1619        if (e.x1 < e.x0 || e.h <= 0) {
 
 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) {
 
 1647    if (gui->kp_size == gui->kp_used) { 
 
 1648        struct keypad_entry *
a = 
ast_realloc(gui->kp, 
sizeof(e)*(gui->kp_size+10));
 
 1656    if (gui->kp_size == gui->kp_used)
 
 1658    gui->kp[gui->kp_used++] = e;
 
Asterisk main include file. File version handling, generic pbx functions.
#define ast_realloc(p, len)
A wrapper for realloc()
#define ast_calloc(num, len)
A wrapper for calloc()
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
#define ast_cli_command(fd, s)
static void sdl_setup(struct video_desc *env)
static void eventhandler(struct video_desc *env, const char *caption)
static struct gui_info * cleanup_sdl(struct gui_info *g, int n)
static int keypad_cfg_read(struct gui_info *gui, const char *val)
static void show_frame(struct video_desc *env, int out)
void delete_board(struct board *b)
deallocates memory space for a board
struct grab_desc * console_grabbers[]
void move_message_board(struct board *b, int dy)
const char * read_message(const struct board *b)
return the whole text from a board
int reset_board(struct board *b)
reset the board to blank
#define MAX_VIDEO_SOURCES
int print_message(struct board *b, const char *s)
Asterisk internal frame definitions.
Asterisk locking-related definitions:
static force_inline int attribute_pure ast_strlen_zero(const char *s)
char * ast_trim_blanks(char *str)
Trims trailing whitespace characters from a string.
char *attribute_pure ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
enum drag_window drag_window
void *(* open)(const char *name, struct fbuf_t *geom, int fps)
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
int error(const char *format,...)