pa_module *module;
pa_client *client;
SmcConn connection;
- pa_x11_wrapper *x11;
+
+ pa_x11_wrapper *x11_wrapper;
+ pa_x11_client *x11_client;
};
+static void x11_kill_cb(pa_x11_wrapper *w, void *userdata) {
+ struct userdata *u = userdata;
+
+ pa_assert(w);
+ pa_assert(u);
+ pa_assert(u->x11_wrapper == w);
+
+ pa_log_debug("X11 client kill callback called");
+
+ if (u->connection) {
+ SmcCloseConnection(u->connection, 0, NULL);
+ u->connection = NULL;
+ }
+
+ if (u->x11_client) {
+ pa_x11_client_free(u->x11_client);
+ u->x11_client = NULL;
+ }
+
+ if (u->x11_wrapper) {
+ pa_x11_wrapper_unref(u->x11_wrapper);
+ u->x11_wrapper = NULL;
+ }
+
+ pa_module_unload_request(u->module, true);
+}
+
static void die_cb(SmcConn connection, SmPointer client_data) {
struct userdata *u = client_data;
pa_assert(u);
pa_log_debug("Got die message from XSMP.");
- pa_x11_wrapper_kill_deferred(u->x11);
-
- pa_x11_wrapper_unref(u->x11);
- u->x11 = NULL;
+ if (u->connection) {
+ SmcCloseConnection(u->connection, 0, NULL);
+ u->connection = NULL;
+ }
- pa_module_unload_request(u->module, true);
+ pa_x11_wrapper_kill_deferred(u->x11_wrapper);
}
static void save_complete_cb(SmcConn connection, SmPointer client_data) {
IceConn connection = userdata;
if (IceProcessMessages(connection, NULL, NULL) == IceProcessMessagesIOError) {
+ pa_log_debug("IceProcessMessages: I/O error, closing ICE connection");
IceSetShutdownNegotiation(connection, False);
IceCloseConnection(connection);
}
c->mainloop->io_free(*watch_data);
}
+static IceIOErrorHandler ice_installed_handler;
+
+/* We call any handler installed before (or after) module is loaded but
+ avoid calling the default libICE handler which does an exit() */
+
+static void ice_io_error_handler(IceConn iceConn) {
+ pa_log_warn("ICE I/O error handler called");
+ if (ice_installed_handler)
+ (*ice_installed_handler) (iceConn);
+}
+
int pa__init(pa_module*m) {
pa_modargs *ma = NULL;
if (ice_in_use) {
pa_log("module-x11-xsmp may not be loaded twice.");
return -1;
- }
+ } else {
+ IceIOErrorHandler default_handler;
+
+ ice_installed_handler = IceSetIOErrorHandler (NULL);
+ default_handler = IceSetIOErrorHandler (ice_io_error_handler);
- IceAddConnectionWatch(new_ice_connection, m->core);
- ice_in_use = true;
+ if (ice_installed_handler == default_handler)
+ ice_installed_handler = NULL;
+
+ IceSetIOErrorHandler(ice_io_error_handler);
+
+ IceAddConnectionWatch(new_ice_connection, m->core);
+ ice_in_use = true;
+ }
m->userdata = u = pa_xnew(struct userdata, 1);
u->core = m->core;
u->module = m;
u->client = NULL;
u->connection = NULL;
- u->x11 = NULL;
+ u->x11_wrapper = NULL;
if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
pa_log("Failed to parse module arguments");
}
}
- if (!(u->x11 = pa_x11_wrapper_get(m->core, pa_modargs_get_value(ma, "display", NULL))))
+ if (!(u->x11_wrapper = pa_x11_wrapper_get(m->core, pa_modargs_get_value(ma, "display", NULL))))
goto fail;
+ u->x11_client = pa_x11_client_new(u->x11_wrapper, NULL, x11_kill_cb, u);
+
e = pa_modargs_get_value(ma, "session_manager", NULL);
if (!e && !getenv("SESSION_MANAGER")) {
if (u->client)
pa_client_free(u->client);
- if (u->x11)
- pa_x11_wrapper_unref(u->x11);
+ if (u->x11_client)
+ pa_x11_client_free(u->x11_client);
+
+ if (u->x11_wrapper)
+ pa_x11_wrapper_unref(u->x11_wrapper);
pa_xfree(u);
}