Thu Jul 9 13:41:16 2009

Asterisk developer's documentation


console_gui.c File Reference

#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

boardboard_setup (SDL_Surface *screen, SDL_Rect *dest, SDL_Surface *font, SDL_Rect *font_rects)
static struct gui_infocleanup_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_infogui_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 Documentation

#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().


Enumeration Type Documentation

anonymous enum

Enumerator:
WIN_LOCAL 
WIN_REMOTE 
WIN_KEYPAD 
WIN_MAX 

Definition at line 46 of file console_gui.c.

enum kp_type

Enumerator:
KP_NONE 
KP_RECT 
KP_CIRCLE 

Definition at line 62 of file console_gui.c.

00062 { KP_NONE, KP_RECT, KP_CIRCLE };

enum skin_area

Enumerator:
KEY_PICK_UP 
KEY_HANG_UP 
KEY_MUTE 
KEY_AUTOANSWER 
KEY_SENDVIDEO 
KEY_LOCALVIDEO 
KEY_REMOTEVIDEO 
KEY_FLASH 
KEY_MESSAGEBOARD 
KEY_DIALEDBOARD 
KEY_EDITBOARD 
KEY_GUI_CLOSE 
KEY_KEYPAD 
KEY_FONT 
KEY_MESSAGE 
KEY_DIALED 
KEY_EDIT 
KEY_OUT_OF_KEYPAD 
KEY_REM_DPY 
KEY_LOC_DPY 
KEY_RESET 
KEY_NONE 
KEY_DIGIT_BACKGROUND 

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 };


Function Documentation

struct 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  )  [static]

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]


Variable Documentation

struct _s_k gui_key_map[] [static]

Definition at line 890 of file console_gui.c.

Referenced by gui_map_token().

const char* us_kbd_map[] [static]

Definition at line 457 of file console_gui.c.


Generated on Thu Jul 9 13:41:16 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7