diff --git a/src/friendlist.c b/src/friendlist.c index 04f422a..29b4bbb 100644 --- a/src/friendlist.c +++ b/src/friendlist.c @@ -115,7 +115,7 @@ void kill_friendlist(void) int i; for (i = 0; i <= Friends.max_idx; ++i) { - if (Friends.list[i].group_invite.key != NULL) + if (Friends.list[i].active && Friends.list[i].group_invite.key != NULL) free(Friends.list[i].group_invite.key); } diff --git a/src/notify.c b/src/notify.c index b0f4259..25c7639 100644 --- a/src/notify.c +++ b/src/notify.c @@ -35,6 +35,7 @@ #include "settings.h" #include "line_info.h" #include "misc_tools.h" +#include "xtra.h" #if defined(AUDIO) || defined(SOUND_NOTIFY) #ifdef __APPLE__ @@ -53,10 +54,6 @@ #endif #endif /* AUDIO */ -#ifdef X11 - #include -#endif /* X11 */ - #ifdef BOX_NOTIFY #include #endif @@ -70,11 +67,7 @@ extern struct user_settings *user_settings; struct Control { time_t cooldown; time_t notif_timeout; -#ifdef X11 - Display *display; - unsigned long this_window; -#endif /* X11 */ - + #if defined(SOUND_NOTIFY) || defined(BOX_NOTIFY) pthread_mutex_t poll_mutex[1]; bool poll_active; @@ -122,23 +115,11 @@ static void tab_notify(ToxWindow *self, uint64_t flags) self->alert = WINDOW_ALERT_2; } -#ifdef X11 -long unsigned int get_focused_window_id() -{ - if (!Control.display) return 0; - - Window focus; - int revert; - XGetInputFocus(Control.display, &focus, &revert); - return focus; -} -#endif /* X11 */ - static bool notifications_are_disabled(uint64_t flags) { bool res = flags & NT_RESTOL && Control.cooldown > get_unix_time(); #ifdef X11 - return res || (flags & NT_NOFOCUS && Control.this_window == get_focused_window_id()); + return res || (flags & NT_NOFOCUS && xtra_is_this_focused()); #else return res; #endif @@ -383,10 +364,6 @@ int init_notify(int login_cooldown, int notification_timeout) #endif Control.cooldown = time(NULL) + login_cooldown; -#ifdef X11 - Control.display = XOpenDisplay(NULL); - Control.this_window = get_focused_window_id(); -#endif /* X11 */ #ifdef BOX_NOTIFY diff --git a/src/toxic.c b/src/toxic.c index 0bba549..be880b5 100644 --- a/src/toxic.c +++ b/src/toxic.c @@ -58,18 +58,19 @@ #include "message_queue.h" #include "execute.h" -#ifdef AUDIO -#include "audio_call.h" -#endif /* AUDIO */ - -#ifndef PACKAGE_DATADIR -#define PACKAGE_DATADIR "." +#ifdef X11 + #include "xtra.h" #endif #ifdef AUDIO +#include "audio_call.h" ToxAv *av; #endif /* AUDIO */ +#ifndef PACKAGE_DATADIR + #define PACKAGE_DATADIR "." +#endif + /* Export for use in Callbacks */ char *DATA_FILE = NULL; char *BLOCK_FILE = NULL; @@ -1002,36 +1003,40 @@ int main(int argc, char *argv[]) const char *p = arg_opts.config_path[0] ? arg_opts.config_path : NULL; int settings_err = settings_load(user_settings, p); +#ifdef X11 + xtra_init(); +#endif + Tox *m = init_tox(); - + if (m == NULL) exit_toxic_err("failed in main", FATALERR_NETWORKINIT); - + if (!arg_opts.ignore_data_file) { if (arg_opts.encrypt_data && !datafile_exists) arg_opts.encrypt_data = 0; - + load_data(m, DATA_FILE); - + } - + init_term(); prompt = init_windows(m); prompt_init_statusbar(prompt, m); - + /* thread for ncurses stuff */ if (pthread_mutex_init(&Winthread.lock, NULL) != 0) exit_toxic_err("failed in main", FATALERR_MUTEX_INIT); - + if (pthread_create(&Winthread.tid, NULL, thread_winref, (void *) m) != 0) exit_toxic_err("failed in main", FATALERR_THREAD_CREATE); - + /* thread for message queue */ if (pthread_create(&cqueue_thread.tid, NULL, thread_cqueue, (void *) m) != 0) exit_toxic_err("failed in main", FATALERR_THREAD_CREATE); - -#ifdef AUDIO - + + #ifdef AUDIO + av = init_audio(prompt, m); set_primary_device(input, user_settings->audio_in_dev); diff --git a/src/xtra.c b/src/xtra.c new file mode 100644 index 0000000..d4edceb --- /dev/null +++ b/src/xtra.c @@ -0,0 +1,132 @@ +#include "xtra.h" + +#include +#include +// #include +// #include + +#include +#include + +static Display *the_d = NULL; +static Window self_window; /* We will assume that during initialization + * we have this window focused */ + +/* For dnd protocol NOTE: copied from utox's code */ +Atom XdndAware, + XdndEnter, + XdndLeave, + XdndPosition, + XdndStatus, + XdndDrop, + XdndSelection, + XdndDATA, + XdndActionCopy; + +void *event_loop(void* p) +{ + (void) p; + + XEvent event; + while (the_d) + { + XNextEvent(the_d, &event); + + switch (event.type) + { + case ClientMessage: + { + + assert(0); + if(event.xclient.message_type == XdndEnter) { + } else if(event.xclient.message_type == XdndPosition) { + Window src = event.xclient.data.l[0]; + XEvent event = { + .xclient = { + .type = ClientMessage, + .display = the_d, + .window = src, + .message_type = XdndStatus, + .format = 32, + .data = { + .l = {self_window, 1, 0, 0, XdndActionCopy} + } + } + }; + XSendEvent(the_d, src, 0, 0, &event); + } else if(event.xclient.message_type == XdndStatus) { + } else if(event.xclient.message_type == XdndDrop) { + XConvertSelection(the_d, XdndSelection, XA_STRING, XdndDATA, self_window, CurrentTime); + } else if(event.xclient.message_type == XdndLeave) { + } else { + } + + goto exit; + } break; + + default: + break; + } + } + +exit: + /* Actual XTRA termination + * Please call xtra_terminate() at exit + * otherwise bad stuff happens + */ + if (the_d) XCloseDisplay(the_d); + return NULL; +} + +void xtra_init() +{ + the_d = XOpenDisplay(NULL); + self_window = xtra_focused_window_id(); + + XSelectInput(the_d, self_window, ExposureMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | + PointerMotionMask | StructureNotifyMask | KeyPressMask | KeyReleaseMask | FocusChangeMask | + PropertyChangeMask); + + XdndAware = XInternAtom(the_d, "XdndAware", False); + XdndEnter = XInternAtom(the_d, "XdndEnter", False); + XdndLeave = XInternAtom(the_d, "XdndLeave", False); + XdndPosition = XInternAtom(the_d, "XdndPosition", False); + XdndStatus = XInternAtom(the_d, "XdndStatus", False); + XdndDrop = XInternAtom(the_d, "XdndDrop", False); + XdndSelection = XInternAtom(the_d, "XdndSelection", False); + XdndDATA = XInternAtom(the_d, "XdndDATA", False); + XdndActionCopy = XInternAtom(the_d, "XdndActionCopy", False); + + Atom Xdndversion = 3; + XChangeProperty(the_d, self_window, XdndAware, XA_ATOM, 32, 0, (unsigned char*)&Xdndversion, 1); + /*XSelectInput(the_d, self_window, ExposureMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | StructureNotifyMask | KeyPressMask | KeyReleaseMask);*/ + pthread_t id; + pthread_create(&id, NULL, event_loop, NULL); + pthread_detach(id); +} + +void xtra_terminate() +{ + XEvent terminate_event; + terminate_event.xclient.display = the_d; + terminate_event.type = ClientMessage; + + + XDeleteProperty(the_d, self_window, XdndAware); + XSendEvent(the_d, self_window, 0, NoEventMask, &terminate_event); +} + +long unsigned int xtra_focused_window_id() +{ + if (!the_d) return 0; + + Window focus; + int revert; + XGetInputFocus(the_d, &focus, &revert); + return focus; +} + +int xtra_is_this_focused() +{ + return self_window == xtra_focused_window_id(); +} diff --git a/src/xtra.h b/src/xtra.h new file mode 100644 index 0000000..1159adf --- /dev/null +++ b/src/xtra.h @@ -0,0 +1,12 @@ +#ifndef XTRA_H +#define XTRA_H + +/* NOTE: If no xlib present don't compile */ + +void xtra_init(); +void xtra_terminate(); + +long unsigned int xtra_focused_window_id(); +int xtra_is_this_focused(); /* returns bool */ + +#endif /* DND_H */ \ No newline at end of file