From e8e14035551f3e683c48eeedb1cedc07a95916cb Mon Sep 17 00:00:00 2001 From: Olaf Wintermann Date: Sun, 16 Jan 2022 10:44:37 +0100 Subject: [PATCH] add handler for motion/button events --- application/main.c | 24 +++++++++++- application/main.h | 4 ++ application/player.c | 18 ++++++++- application/window.c | 107 ++++++++++++++++++++++++++++++++++++++++----------- application/window.h | 8 ++++ 5 files changed, 135 insertions(+), 26 deletions(-) diff --git a/application/main.c b/application/main.c index 18d534b..43d6c05 100644 --- a/application/main.c +++ b/application/main.c @@ -133,7 +133,7 @@ int main(int argc, char** argv) { srand(time(NULL)); WindowShow(window); - XtAppMainLoop(app); + AppMainLoop(app); return 0; } @@ -160,3 +160,25 @@ char* GetOpenFileArg(void) { void CleanOpenFileArg(void) { open_file_arg = NULL; } + +static Window app_player_window = 0; + +void SetPlayerWindow(Window w) { + app_player_window = w; +} + +/* + * Extended Xt main loop, that also handles external window events + */ +void AppMainLoop(XtAppContext app) { + while(!XtAppGetExitFlag(app)) { + XEvent event; + XtAppNextEvent(app, &event); + + if(app_player_window != 0 && event.xany.window == app_player_window) { + WindowPlayerWidgetEvent(GetMainWindow(), &event); + } else { + XtDispatchEvent(&event); + } + } +} diff --git a/application/main.h b/application/main.h index be957b8..e39b827 100644 --- a/application/main.h +++ b/application/main.h @@ -41,6 +41,10 @@ void AppExecProc(XtWorkProc proc, XtPointer data); char* GetOpenFileArg(void); void CleanOpenFileArg(void); +void SetPlayerWindow(Window w); + +void AppMainLoop(XtAppContext app); + #ifdef __cplusplus } diff --git a/application/player.c b/application/player.c index 9e65410..6cdba87 100644 --- a/application/player.c +++ b/application/player.c @@ -110,6 +110,7 @@ static void* wait_for_process(void *data) { player->isactive = FALSE; player->status = status; + SetPlayerWindow(0); return NULL; } @@ -329,7 +330,6 @@ static void handle_json_rpc_msg(Player *player, JSONValue *v) { } //json_print(v, NULL, 0); - fflush(stdout); } static Boolean player_widget_set_size(XtPointer data) { @@ -411,6 +411,9 @@ static Boolean get_player_window(XtPointer data) { if(nchild > 0) { p->window = child[0]; XFree(child); + + SetPlayerWindow(p->window); + XSelectInput(XtDisplay(win->player_widget), p->window, PointerMotionMask); } return 0; @@ -420,14 +423,24 @@ static void handle_json_rpc_event(Player *p, JSONValue *v, JSONValue *event) { if(!json_strcmp(event, "property-change")) { JSONValue *name = json_obj_get(&v->value.object, "name"); JSONValue *data = json_obj_get(&v->value.object, "data"); - if(!json_strcmp(name, "eof-reached")) { + if(!json_strcmp(name, "playback-time")) { + if(data && data->type == JSON_NUMBER) { + p->playback_time = data->value.number.value; + //printf("playback-time: %f\n", p->playback_time); + } + } else if(!json_strcmp(name, "eof-reached")) { if(data && data->type == JSON_LITERAL && data->value.literal.literal == JSON_TRUE) { PlayerEOF(p); } + } else if(!json_strcmp(name, "osd-height")) { + if(data->type == JSON_NUMBER) { + p->osd_height = data->value.number.value; + } } } else if(!p->isstarted && !json_strcmp(event, "playback-restart")) { char *cmd = "{ \"command\": [\"observe_property\", 1, \"playback-time\"] }\n" "{ \"command\": [\"observe_property\", 1, \"eof-reached\"] }\n" + "{ \"command\": [\"observe_property\", 1, \"osd-height\"] }\n" "{ \"command\": [\"get_property\", \"width\"], request_id=\"" REQ_ID_WIDTH "\" }\n" "{ \"command\": [\"get_property\", \"height\"], request_id=\"" REQ_ID_HEIGHT "\" }\n" "{ \"command\": [\"set_property\", \"keep-open\", true] }\n"; @@ -454,6 +467,7 @@ void PlayerDestroy(Player *p) { kill(p->process, SIGTERM); } + SetPlayerWindow(0); free(p); } diff --git a/application/window.c b/application/window.c index e7c85df..26092cd 100644 --- a/application/window.c +++ b/application/window.c @@ -39,6 +39,24 @@ static void ViewFullscreenCB(Widget w, void *udata, void *cdata); static void WindowRealized(MainWindow *win); +static int blank_cursor_init = 0; +static Pixmap blank_cursor_pixmap; +static Cursor blank_cursor; + +static void init_blank_cursor(Widget w) { + char data = 0; + + XColor c; + + blank_cursor_pixmap = XCreateBitmapFromData(XtDisplay(w), XtWindow(w), &data, 1, 1); + if(!blank_cursor_pixmap) return; + + blank_cursor = XCreatePixmapCursor(XtDisplay(w), blank_cursor_pixmap, blank_cursor_pixmap, &c, &c, 0, 0); + + XFreePixmap(XtDisplay(w), blank_cursor_pixmap); + blank_cursor_init = 1; +} + static void window_close_handler(Widget window, void *udata, void *cdata) { WindowClosePlayer(main_window); ApplicationExit(); @@ -56,7 +74,7 @@ static void windowKeyEH(Widget widget, XtPointer data, XEvent *event, Boolean *d static int main_window_is_realized = 0; -static void resizeEH(Widget widget, XtPointer data, XEvent *event, Boolean *dispatch) { +static void resizeEH(Widget widget, XtPointer data, XEvent *event, Boolean *dispatch) { if(!main_window_is_realized) { if(XtIsRealized(widget)) { main_window_is_realized = 1; @@ -77,6 +95,10 @@ static void WindowRealized(MainWindow *win) { PlayerOpenFile(win); CleanOpenFileArg(); } + + if(!blank_cursor_init) { + init_blank_cursor(win->player_widget); + } } static void playerWidgetInputCB(Widget widget, XtPointer u, XtPointer c) { @@ -88,40 +110,51 @@ static void playerWidgetInputCB(Widget widget, XtPointer u, XtPointer c) { } } -static void playerEH(Widget widget, XtPointer data, XEvent *event, Boolean *dispatch) { - MainWindow *win = data; - if(!win->player || win->player->window == 0) return; - - /* - if(event->type == EnterNotify) { - printf("enter: grab pointer\n"); - - XtGrabPointer( +static void windowGrabButton(MainWindow *win) { + //printf("grab\n"); + XtGrabButton( win->player_widget, + AnyButton, + AnyModifier, True, ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask | EnterWindowMask | LeaveWindowMask, GrabModeAsync, GrabModeAsync, None, - None, - CurrentTime); - + None); + win->buttongrab = True; +} + +static void playerEH(Widget widget, XtPointer data, XEvent *event, Boolean *dispatch) { + MainWindow *win = data; + int etype = event->type; + + ///* + if(etype == EnterNotify) { + //printf("enter\n"); + windowGrabButton(win); return; } - if(event->type == LeaveNotify) { - printf("leave\n"); - XtUngrabPointer(win->player_widget, CurrentTime); + if(etype == LeaveNotify) { + //printf("leave\n"); + //XtUngrabButton(win->player_widget, AnyButton, AnyModifier); + //win->buttongrab = False; return; } - if(event->type == MotionNotify) { - static int testv = 0; - printf("test %d\n", testv++); + int pass = 0; + if(etype == ButtonPress || etype == ButtonRelease || etype == KeyPress || etype == KeyRelease) { + //printf("button press\n"); + pass = 1; } - */ - if(event->type == KeyPress || event->type == KeyRelease) { + if(!win->player || win->player->window == 0) return; + + WindowPlayerWidgetEvent(win, event); + + if(pass) { // redirect key events to the player window + //printf("redirect\n"); event->xkey.window = win->player->window; XSendEvent( XtDisplay(win->player_widget), @@ -132,10 +165,22 @@ static void playerEH(Widget widget, XtPointer data, XEvent *event, Boolean *disp } } +void WindowPlayerWidgetEvent(MainWindow *win, XEvent *event) { + int etype = event->type; + + if(etype == MotionNotify) { + + } else if(etype == ButtonPress) { + + } else if(etype == ButtonRelease) { + + } +} + MainWindow* WindowCreate(Display *display) { Arg args[32]; int n; - + MainWindow *window = malloc(sizeof(MainWindow)); memset(window, 0, sizeof(MainWindow)); main_window = window; @@ -423,7 +468,7 @@ static void ViewFullscreenCB(Widget w, void *udata, void *cdata) { void WindowAdjustAspectRatio(MainWindow *win) { if(!win->player) return; if(!win->player->isactive || win->player->width <= 0 || win->player->height <= 0) return; - + // we have a running player width video // adjust window aspect ratio (the window aspect ratio is different from // the video, because of window decoration, menubar and other extra controls) @@ -455,3 +500,19 @@ void WindowClosePlayer(MainWindow *win) { } win->player = NULL; } + +void WindowHidePlayerCursor(MainWindow *win) { + if(!win->cursorhidden && win->player && win->player->window != 0) { + //XDefineCursor(XtDisplay(win->player_widget), XtWindow(win->player_widget), blank_cursor); + win->cursorhidden = True; + XFlush(XtDisplay(win->player_widget)); + } +} + +void WindowShowPlayerCursor(MainWindow *win) { + if(win->cursorhidden && win->player && win->player->window != 0) { + XDefineCursor(XtDisplay(win->player_widget), XtWindow(win->player_widget), None); + win->cursorhidden = False; + XFlush(XtDisplay(win->player_widget)); + } +} diff --git a/application/window.h b/application/window.h index 82623e7..4424273 100644 --- a/application/window.h +++ b/application/window.h @@ -44,6 +44,7 @@ typedef struct Player { double playback_time; int width; int height; + int osd_height; } Player; typedef struct MainWindow { @@ -54,6 +55,8 @@ typedef struct MainWindow { Player *player; bool fullscreen; bool mbvisible; + bool cursorhidden; + bool buttongrab; } MainWindow; MainWindow* WindowCreate(Display *dp); @@ -72,6 +75,11 @@ void WindowAdjustAspectRatio(MainWindow *win); void WindowClosePlayer(MainWindow *win); +void WindowHidePlayerCursor(MainWindow *win); +void WindowShowPlayerCursor(MainWindow *win); + +void WindowPlayerWidgetEvent(MainWindow *win, XEvent *event); + #ifdef __cplusplus } #endif -- 1.8.3.1