static void send_message(const char* message) { GError *error = NULL; gchar *str = NULL; int message_num; gchar error_return[30]; if (!dbus_g_proxy_call (proxy, "Invoke", &error, G_TYPE_STRING, message, G_TYPE_INVALID, G_TYPE_STRING, &str, G_TYPE_INVALID)) { if (error && error->message) { skype_debug_info("skype_dbus", "Error sending message: %s\n", error->message); if (message[0] == '#') { //We're expecting a response sscanf(message, "#%d ", &message_num); sprintf(error_return, "#%d ERROR", message_num); skype_message_received(g_strdup(error_return)); } } else { skype_debug_info("skype_dbus", "no response\n"); } } if (str != NULL) { skype_message_received(str); } }
static gboolean exec_skype() { 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; } }
static void skype_message_received(char *orig_message) { guint request_number; guint *key; int string_pos; char *message; if (strlen(orig_message) == 0) return; message = g_strdup(orig_message); g_free(orig_message); skype_debug_info("skype", "Received: %s\n", message); if(message[0] == '#') { //It's a reply from a call we've made - update the hash table sscanf(message, "#%u %n", &request_number, &string_pos); key = g_new(guint, 1); *key = request_number; g_static_mutex_lock2(&mutex); g_hash_table_insert(message_queue, key, g_strdup(&message[string_pos])); g_cond_broadcast(condition); g_static_mutex_unlock2(&mutex); g_free(message); } else { purple_timeout_add(1, (GSourceFunc)skype_handle_received_message, (gpointer)message); } }
static gboolean skype_connect() { GError *error = NULL; DBusObjectPathVTable vtable; //Initialise threading dbus_threads_init_default(); if (connection == NULL) { connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); if (connection == NULL && error != NULL) { skype_debug_info("skype_dbus", "Error: %s\n", error->message); g_error_free(error); return FALSE; } } if (proxy == NULL) { proxy = dbus_g_proxy_new_for_name_owner (connection, "com.Skype.API", "/com/Skype", "com.Skype.API", &error); if (proxy == NULL && error != NULL) { skype_debug_warning("skype_dbus", "%s\n", error->message); g_error_free(error); return FALSE; } g_signal_connect(G_OBJECT(proxy), "destroy", G_CALLBACK(skype_destroy_handler), NULL); #ifdef DBUS_MAJOR_VERSION dbus_g_proxy_set_default_timeout(proxy, 3000); #endif vtable.message_function = &skype_notify_handler; dbus_connection_register_object_path(dbus_g_connection_get_connection(connection), "/com/Skype/Client", &vtable, NULL); } return TRUE; }
void connect_function(gpointer data, gint source, const gchar *error_message) { gchar *loginmsg; PurpleAccount *acct = skype_get_account(NULL); if (error_message) { in_progress = FALSE; g_thread_create((GThreadFunc)skype_message_received, g_strdup("CONNSTATUS LOGGEDOUT"), FALSE, NULL); return; } source_sock = source; loginmsg = g_strdup_printf("LOGIN %s %s", acct->username, acct->password); send_message(loginmsg); skype_debug_info("skype", "Sending: 'LOGIN {username} {password}'\n"); g_free(loginmsg); g_thread_create((GThreadFunc)skype_read_thread, NULL, FALSE, NULL); }
void skype_send_message_nowait(char *message_format, ...) { va_list args; char* message; va_start(args, message_format); message = g_strdup_vprintf(message_format, args); va_end(args); skype_debug_info("skype", "Sending: '%s'\n", message); if (send_messages_queue == NULL) send_messages_queue = g_async_queue_new(); if (send_messages_thread == NULL) { send_messages_thread = g_thread_create(send_messages_thread_func, NULL, FALSE, NULL); } g_async_queue_push(send_messages_queue, message); }
void read_function_cb(gpointer data, gint source, PurpleInputCondition cond) { int len; gchar response[3096]; static GString *response_string = NULL; gchar *reply; gchar **reply_pieces; int i; len = read(source, response, sizeof(response)-1); if (len < 0) { if (errno != EAGAIN && errno != EWOULDBLOCK) { skype_disconnect(); } return; } if (len == sizeof(response)-1) { if (response_string == NULL) response_string = g_string_new_len(response, len); else response_string = g_string_append_len(response_string, response, len); } else { if (response_string) { if (len > 0) response_string = g_string_append_len(response_string, response, len); reply = g_string_free(response_string, FALSE); response_string = NULL; } else if (len) reply = g_strndup(response, len); else return; reply = g_strstrip(reply); reply_pieces = g_strsplit(reply, etb_string, -1); g_free(reply); for (i=0; reply_pieces[i+1]; i++) { reply = reply_pieces[i]; if (g_str_equal(reply, "LOGIN")) { connected = TRUE; in_progress = FALSE; skype_debug_info("skype", "Received: LOGIN\n"); } else { g_thread_create((GThreadFunc)skype_message_received, g_strdup(reply), FALSE, NULL); } } //check that we received part of a message if (strlen(reply_pieces[i])) { skype_debug_info("skype", "Last piece: '%s'\n", reply_pieces[i]); response_string = g_string_new(reply_pieces[i]); } g_strfreev(reply_pieces); } }
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 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); } } } }