diff options
Diffstat (limited to 'skype_messaging_x11.c')
-rw-r--r-- | skype_messaging_x11.c | 392 |
1 files changed, 0 insertions, 392 deletions
diff --git a/skype_messaging_x11.c b/skype_messaging_x11.c deleted file mode 100644 index 50f79f3..0000000 --- a/skype_messaging_x11.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Skype plugin for libpurple/Pidgin/Adium - * Written by: Eion Robb <eionrobb@gmail.com> - * - * This plugin uses the Skype API to show your contacts in libpurple, and send/receive - * chat messages. - * It requires the Skype program to be running. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef INCLUDED_LIBSKYPE_C -# error "Don't compile this file directly. Just compile libskype.c instead." -#endif - -#include <X11/Xlib.h> -#include <X11/Xatom.h> - -static Display *disp = NULL; -static Window win = (Window)None; -Window skype_win = (Window)None; -static GThread *receiving_thread = NULL; -Atom message_start, message_continue; -static gboolean run_loop = FALSE; -static unsigned char x11_error_code = 0; -static GStaticMutex x11_mutex = G_STATIC_MUTEX_INIT; - -static void receive_message_loop(void); -int x11_error_handler(Display *disp, XErrorEvent *error); - -static gboolean -skype_connect() -{ - Window root; - Atom skype_inst; - Atom type_ret; - int format_ret; - unsigned long nitems_ret; - unsigned long bytes_after_ret; - unsigned char *prop; - int status; - - x11_error_code = 0; - XSetErrorHandler(x11_error_handler); - skype_debug_info("skype_x11", "Set the XErrorHandler\n"); -#ifdef USE_XVFB_SERVER - if (!getenv("SKYPEDISPLAY")) - setenv("SKYPEDISPLAY", ":25", 0); -#endif - if (getenv("SKYPEDISPLAY")) - disp = XOpenDisplay(getenv("SKYPEDISPLAY")); - else - disp = XOpenDisplay(getenv("DISPLAY")); - if (disp == NULL) - { - skype_debug_info("skype_x11", "Couldn't open display\n"); - return FALSE; - } - skype_debug_info("skype_x11", "Opened display\n"); - message_start = XInternAtom( disp, "SKYPECONTROLAPI_MESSAGE_BEGIN", False ); - message_continue = XInternAtom( disp, "SKYPECONTROLAPI_MESSAGE", False ); - root = DefaultRootWindow( disp ); - win = XCreateSimpleWindow( disp, root, 0, 0, 1, 1, - 0, BlackPixel( disp, DefaultScreen( disp ) ), - BlackPixel( disp, DefaultScreen( disp ) )); - XFlush(disp); - if (win == None) - { - XCloseDisplay(disp); - disp = NULL; - skype_debug_info("skype_x11", "Could not create X11 messaging window\n"); - return FALSE; - } - skype_debug_info("skype_x11", "Created X11 messaging window\n"); - skype_inst = XInternAtom(disp, "_SKYPE_INSTANCE", True); - if (skype_inst == None) - { - XDestroyWindow(disp, win); - XCloseDisplay(disp); - win = (Window)None; - disp = NULL; - skype_debug_info("skype_x11", "Could not create skype Atom\n"); - return FALSE; - } - skype_debug_info("skype_x11", "Created skype Atom\n"); - status = XGetWindowProperty(disp, root, skype_inst, 0, 1, False, XA_WINDOW, &type_ret, &format_ret, &nitems_ret, &bytes_after_ret, &prop); - if(status != Success || format_ret != 32 || nitems_ret < 1) - { - XDestroyWindow(disp, win); - XCloseDisplay(disp); - win = (Window)None; - XFree(prop); - disp = NULL; - skype_debug_info("skype", "Skype instance not found\n"); - return FALSE; - } - skype_debug_info("skype_x11", "Skype instance found\n"); - skype_win = * (const unsigned long *) prop & 0xffffffff; - XFree(prop); - run_loop = TRUE; - - skype_debug_info("skype_x11", "Charging lasers...\n"); - receiving_thread = g_thread_create((GThreadFunc)receive_message_loop, NULL, FALSE, NULL); - - return TRUE; -} - - -static void -skype_disconnect() -{ - run_loop = FALSE; - skype_win = (Window)None; - - if (disp != NULL) - { - if (win != None) - { - //wait here for the event to be handled - XDestroyWindow(disp, win); - } - XCloseDisplay(disp); - } - - win = (Window)None; - disp = NULL; -} - -int -x11_error_handler(Display *disp, XErrorEvent *error) -{ - x11_error_code = error->error_code; - return FALSE; -} - - -static void -send_message(const char* message) -{ - unsigned int pos = 0; - unsigned int len = strlen( message ); - XEvent e; - int message_num; - char *error_return; - unsigned int i; - - if (skype_win == None || win == None || disp == NULL) - { - //There was an error - if (message[0] == '#') - { - //And we're expecting a response - sscanf(message, "#%d ", &message_num); - error_return = g_strdup_printf("#%d ERROR X11", message_num); - g_thread_create((GThreadFunc)skype_message_received, (void *)error_return, FALSE, NULL); - } - return; - } - - memset(&e, 0, sizeof(e)); - e.xclient.type = ClientMessage; - e.xclient.message_type = message_start; /* first message */ - e.xclient.display = disp; - e.xclient.window = win; - e.xclient.format = 8; /* 8-bit values */ - - do - { - for( i = 0; i < 20 && i + pos <= len; ++i ) - e.xclient.data.b[ i ] = message[ i + pos ]; - g_static_mutex_lock(&x11_mutex); - XSendEvent( disp, skype_win, False, 0, &e ); - g_static_mutex_unlock(&x11_mutex); - - e.xclient.message_type = message_continue; /* 2nd or greater message */ - pos += i; - } while( pos <= len ); - - //XFlush(disp); - - if (x11_error_code == BadWindow) - { - //There was an error - if (message[0] == '#') - { - //And we're expecting a response - sscanf(message, "#%d ", &message_num); - error_return = g_strdup_printf("#%d ERROR X11_2", message_num); - g_thread_create((GThreadFunc)skype_message_received, (void *)error_return, FALSE, NULL); - } - g_thread_create((GThreadFunc)skype_message_received, g_strdup("CONNSTATUS LOGGEDOUT"), FALSE, NULL); - return; - } -} - -static void -receive_message_loop(void) -{ - XEvent e; - GString *msg = NULL; - char msg_temp[21]; - size_t len; - - skype_debug_info("skype_x11", "receive_message_loop started\n"); - - msg_temp[20] = '\0'; - XSetErrorHandler(x11_error_handler); - while(run_loop) - { - if (!disp) - { - skype_debug_error("skype_x11", "display has disappeared\n"); - g_thread_create((GThreadFunc)skype_message_received, g_strdup("CONNSTATUS LOGGEDOUT"), FALSE, NULL); - break; - } - - Bool event_bool; - g_static_mutex_lock(&x11_mutex); - event_bool = XCheckTypedEvent(disp, ClientMessage, &e); - g_static_mutex_unlock(&x11_mutex); - if (!event_bool) - { - g_thread_yield(); - usleep(1000); - //XPeekEvent(disp, &e); - //sleep(1); - continue; - }/* - XNextEvent(disp, &e); - printf("skype event: %d (clientmessage: %d)\n", e.type, ClientMessage); - if (e.type != ClientMessage) - continue;*/ - - strncpy(msg_temp, e.xclient.data.b, 20); - len = strlen(msg_temp); - if (e.xclient.message_type == message_start) - msg = g_string_new_len(msg_temp, len); - else if (e.xclient.message_type == message_continue) - msg = g_string_append_len(msg, msg_temp, len); - else - { - skype_debug_info("skype_x11", "unknown message type: %d\n", e.xclient.message_type); - if (disp) - { - g_static_mutex_lock(&x11_mutex); - XFlush(disp); - g_static_mutex_unlock(&x11_mutex); - } - continue; - } - if (len < 20) - { - g_thread_create((GThreadFunc)skype_message_received, (void *)g_string_free(msg, FALSE), FALSE, NULL); - if (disp) - { - g_static_mutex_lock(&x11_mutex); - XFlush(disp); - g_static_mutex_unlock(&x11_mutex); - } - } - } -} - -static void -hide_skype() -{ - -} - -static gboolean -exec_skype() -{ -#ifdef INSTANTBIRD - return FALSE; -#else - GError *error; - -#ifdef USE_XVFB_SERVER - PurpleAccount *acct = NULL; - int skype_stdin; - gchar **skype_list; - gchar *command; - - if (!getenv("SKYPEDISPLAY")) - setenv("SKYPEDISPLAY", ":25", 0); - unsetenv("DBUS_SESSION_BUS_ADDRESS"); - command = g_strconcat("Xvfb ", - //"Xnest ", //Uncomment if using Xnest - getenv("SKYPEDISPLAY"), - " -ac -terminate -tst -xinerama", - " -render -shmem -screen 0 320x240x16", //Dont use me if using Xnest - NULL); - if (g_spawn_command_line_async(command, NULL)) - { - acct = skype_get_account(NULL); - skype_debug_info("skype_x11", "acct: %d\n", acct); - if (acct && acct->username && acct->username[0] != '\0' && - acct->password && acct->password[0] != '\0') - { - g_free(command); - command = g_strconcat("skype --pipelogin -display ", - getenv("SKYPEDISPLAY"), - NULL); - g_shell_parse_argv(command, NULL, &skype_list, NULL); - if (g_spawn_async_with_pipes(NULL, skype_list, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &skype_stdin, NULL, NULL, NULL)) - { - g_strfreev(skype_list); - write(skype_stdin, acct->username, strlen(acct->username)); - write(skype_stdin, " ", 1); - write(skype_stdin, acct->password, strlen(acct->password)); - write(skype_stdin, "\n", 1); - fsync(skype_stdin); - skype_debug_info("skype_x11", "pipelogin worked\n"); - g_free(command); - return TRUE; - } - g_strfreev(skype_list); - } - } - g_free(command); -#endif - - if (g_spawn_command_line_async("skype --disable-cleanlooks", &error)) - { - return TRUE; - } else { - skype_debug_error("skype", "Could not start skype: %s\n", error->message); - return FALSE; - } -#endif -} - -static gboolean -is_skype_running() -{ - const gchar *temp; - int pid; - gchar* stat_path; - FILE *fh; - gchar exec_name[16]; - struct stat *statobj = g_new(struct stat, 1); - //open /proc - GDir *procdir = g_dir_open("/proc", 0, NULL); - //go through directories that are numbers - while((temp = g_dir_read_name(procdir))) - { - pid = atoi(temp); - if (!pid) - continue; - // /proc/{pid}/stat contains lots of juicy info - stat_path = g_strdup_printf("/proc/%d/stat", pid); - fh = fopen(stat_path, "r"); - if (!fh) - { - g_free(stat_path); - continue; - } - pid = fscanf(fh, "%*d (%15[^)]", exec_name); - fclose(fh); - if (!g_str_equal(exec_name, "skype")) - { - g_free(stat_path); - continue; - } - //get uid/owner of stat file by using fstat() - g_stat(stat_path, statobj); - g_free(stat_path); - //compare uid/owner of stat file (in g_stat->st_uid) to getuid(); - if (statobj->st_uid == getuid()) - { - //this copy of skype was started by us - g_dir_close(procdir); - g_free(statobj); - return TRUE; - } - } - g_dir_close(procdir); - g_free(statobj); - return FALSE; -} - |