98 static void show_frame(
struct video_desc *env,
int out) {}
99 static void sdl_setup(
struct video_desc *env) {}
101 static void eventhandler(
struct video_desc *env,
const char *caption) {}
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
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++) {
236 #define IS_SECONDARY 2
261 AVPicture *p_in, p_out;
262 struct fbuf_t *b_in, *b_out;
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];
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);
346 KEY_AUDIO_SRCS = 210,
382 char buf[2] = { digit,
'\0' };
383 if (env->gui->bd_msg)
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;
443 buf[
sizeof(buf) - 1] =
'\0';
444 snprintf(buf,
sizeof(buf),
"console dial %s", who);
472 static int gui_output(
struct video_desc *env,
const char *
text)
479 static void sdl_setup(
struct video_desc *env);
493 src_msgs[env->out.devices[i].status_index]);
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;
547 if (p == &env->out.device_primary)
548 env->out.devices[*p].status_index |=
IS_PRIMARY;
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;
601 p->grabber_data = p->grabber->close(p->grabber_data);
606 p->status_index &= ~
IS_ON;
632 int x0 =
MAX(env->rem_dpy.w+gui->
keypad->w/2+2*
BORDER, src_wins_tot_w/2);
650 else if (button.y >=
MAX(
MAX(env->rem_dpy.h, env->loc_dpy.h), gui->
keypad->h))
652 else if (button.x < x0 - gui->
keypad->w/2 -
BORDER - env->rem_dpy.w)
656 else if (button.x < x0 - gui->
keypad->w/2)
658 else if (button.x >= x0 + gui->
keypad->w/2 +
BORDER + env->loc_dpy.w)
662 else if (button.x >= x0 + gui->
keypad->w/2)
667 int x_keypad = button.x - (x0 - gui->
keypad->w/2);
669 for (i = 0; i < gui->
kp_used; i++) {
671 index = gui->
kp[i].
c;
676 }
else if (button.y <
BORDER) {
679 x = x0 - src_wins_tot_w/2 +
BORDER;
682 else if (button.x < x)
684 else if (button.x < x + src_wins_tot_w -
BORDER) {
689 for (i = 1; i <= env->out.device_num; i++) {
708 else if (index >=
KEY_SRCS_WIN && index < KEY_SRCS_WIN+env->out.device_num) {
712 if (button.button == SDL_BUTTON_RIGHT || button.button == SDL_BUTTON_LEFT) {
722 env->out.devices[index].name);
725 env->out.devices[index].name);
728 env->out.devices[index].name);
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 &&
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) {
799 sprintf(buf,
"%c%dx%d", button.button == SDL_BUTTON_RIGHT ?
'>' :
'<',
807 for (i = 0; i < env->out.device_num; i++) {
840 "`~",
"1!",
"2@",
"3#",
"4$",
"5%",
"6^",
841 "7&",
"8*",
"9(",
"0)",
"-_",
"=+",
"[{",
842 "]}",
"\\|",
";:",
"'\"",
",<",
".>",
"/?",
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')
877 char buf[2] = {
map_key(ks),
'\0' };
889 if (buf[0] ==
'\r' || buf[0] ==
'\n') {
902 static void grabber_move(
struct video_device *,
int dx,
int dy);
907 int delta = end - *start;
910 delta += delta * delta * (delta > 0 ? 1 : -1 )/100;
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;
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) {
996 case SDL_MOUSEMOTION:
997 case SDL_MOUSEBUTTONUP:
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;
1021 if (ev[i].type == SDL_MOUSEBUTTONUP)
1024 case SDL_MOUSEBUTTONDOWN:
1038 fprintf(stderr,
"-------- SDL_PumpEvents took %dms\n", i);
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());
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) {
1113 int w,
int h,
int x,
int y)
1115 win->
bmp = SDL_CreateYUVOverlay(w, h, fmt, screen);
1116 if (win->
bmp == NULL)
1131 const char region[] =
"region";
1132 int reg_len = strlen(region);
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))
1188 if (r[0].w == 0 || r[0].h == 0)
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");
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);
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;
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);
1415 SDL_WM_SetCaption(
"Asterisk console Video Output", NULL);
1419 env->rem_dpy.w, env->rem_dpy.h, x0-kp_w/2-
BORDER-env->rem_dpy.w, y0))
1422 env->frame_freeze = 0;
1425 env->loc_dpy.w, env->loc_dpy.h,
1431 x = x0 - src_wins_tot_w/2 +
BORDER;
1432 for (i = 0; i < env->out.device_num; i++){
1444 SDL_MapRGB(gui->
screen->format, 255, 255, 255));
1460 dest->x = x0-kp_w/2;
1467 SDL_UpdateRects(gui->
screen, 1, dest);
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;
1498 ret = (xp >= 0 && xp < l && yp >=0 && yp < e->
h);
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",
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))
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);
1604 if (strcasecmp(s2,
"circle"))
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")) {
1641 if (gui->
kp == NULL) {
static int turn_on_off(int index, struct video_desc *env)
tries to switch the state of a device from on to off or off to on we also have to update the status o...
union ast_frame_subclass subclass
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 fr...
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
static struct _s_k gui_key_map[]
static struct gui_info * cleanup_sdl(struct gui_info *gui, int device_num)
free the resources in struct gui_info and the descriptor itself. Return NULL so we can assign the val...
int reset_board(struct board *b)
reset the board to blank
static char * keypad_toggle(struct video_desc *env, int index)
static void pip_move(struct video_desc *env, int dx, int dy)
This function moves the picture in picture, controlling the limits of the containing buffer to avoid ...
enum drag_window drag_window
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 keypad_digit(struct video_desc *env, int digit)
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
static int kp_match_area(const struct keypad_entry *e, int x, int y)
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
struct thumb_bd thumb_bd_array[MAX_VIDEO_SOURCES]
void *(* open)(const char *name, struct fbuf_t *geom, int fps)
static void handle_mousedown(struct video_desc *env, SDL_MouseButtonEvent button)
struct grab_desc * console_grabbers[]
static void show_frame(struct video_desc *env, int out)
static int video_geom(struct fbuf_t *b, const char *s)
void delete_board(struct board *b)
deallocates memory space for a board
static int my_x_handler(Display *d, XErrorEvent *e)
static struct gui_info * gui_init(const char *keypad_file, const char *font)
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Asterisk internal frame definitions.
#define MAX_VIDEO_SOURCES
struct board * board_setup(SDL_Surface *screen, SDL_Rect *dest, SDL_Surface *font, SDL_Rect *font_rects)
Initialize the board. return 0 on success, 1 on error TODO, if this is done at reload time...
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.
descriptor for one of our channels.
static struct chan_oss_pvt * find_desc(const char *dev)
returns a pointer to the descriptor with the given name
static const char *const us_kbd_map[]
static int gui_map_token(const char *s)
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
char * ast_trim_blanks(char *str)
Trims trailing whitespace characters from a string.
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 switch_video_out(struct video_desc *env, int index, Uint8 button)
Changes the video output (local video) source, controlling if it is already using that video device...
struct display_window win[WIN_MAX]
void move_message_board(struct board *b, int dy)
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 #...
if(yyss+yystacksize-1<=yyssp)
static void grabber_move(struct video_device *, int dx, int dy)
const char * read_message(const struct board *b)
return the whole text from a board
static void eventhandler(struct video_desc *env, const char *caption)
refresh the screen, and also grab a bunch of events.
char * console_do_answer(int fd)
#define ast_realloc(a, b)
static void keypad_pick_up(struct video_desc *env)
int print_message(struct board *b, const char *s)
static void handle_keyboard_input(struct video_desc *env, SDL_keysym *ks)
static int update_device_info(struct video_desc *env, int i)
Data structure associated with a single frame of data.
static void keypad_setup(struct gui_info *gui, const char *kp_file)
static SDL_Surface * load_image(const char *file)
static char map_key(SDL_keysym *ks)
int compute_drag(int *start, int end, int magnifier)