mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	don't exit when the XSM signals us a session exit. instead just unload all X11 modules
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@2512 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
		
							parent
							
								
									a180edd0a5
								
							
						
					
					
						commit
						c33db3ce68
					
				
					 6 changed files with 196 additions and 58 deletions
				
			
		| 
						 | 
					@ -1361,7 +1361,7 @@ module_x11_publish_la_LIBADD = $(AM_LIBADD) $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EX
 | 
				
			||||||
module_x11_xsmp_la_SOURCES = modules/module-x11-xsmp.c
 | 
					module_x11_xsmp_la_SOURCES = modules/module-x11-xsmp.c
 | 
				
			||||||
module_x11_xsmp_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS)
 | 
					module_x11_xsmp_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS)
 | 
				
			||||||
module_x11_xsmp_la_LDFLAGS = -module -avoid-version
 | 
					module_x11_xsmp_la_LDFLAGS = -module -avoid-version
 | 
				
			||||||
module_x11_xsmp_la_LIBADD = $(AM_LIBADD) $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EXTRA_LIBS) libpulsecore.la
 | 
					module_x11_xsmp_la_LIBADD = $(AM_LIBADD) $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EXTRA_LIBS) libx11wrap.la libpulsecore.la
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# OSS
 | 
					# OSS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,21 +45,11 @@
 | 
				
			||||||
#include "module-x11-bell-symdef.h"
 | 
					#include "module-x11-bell-symdef.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PA_MODULE_AUTHOR("Lennart Poettering");
 | 
					PA_MODULE_AUTHOR("Lennart Poettering");
 | 
				
			||||||
PA_MODULE_DESCRIPTION("X11 Bell interceptor");
 | 
					PA_MODULE_DESCRIPTION("X11 bell interceptor");
 | 
				
			||||||
PA_MODULE_VERSION(PACKAGE_VERSION);
 | 
					PA_MODULE_VERSION(PACKAGE_VERSION);
 | 
				
			||||||
PA_MODULE_LOAD_ONCE(FALSE);
 | 
					PA_MODULE_LOAD_ONCE(FALSE);
 | 
				
			||||||
PA_MODULE_USAGE("sink=<sink to connect to> sample=<sample name> display=<X11 display>");
 | 
					PA_MODULE_USAGE("sink=<sink to connect to> sample=<sample name> display=<X11 display>");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct userdata {
 | 
					 | 
				
			||||||
    pa_core *core;
 | 
					 | 
				
			||||||
    int xkb_event_base;
 | 
					 | 
				
			||||||
    char *sink_name;
 | 
					 | 
				
			||||||
    char *scache_item;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pa_x11_wrapper *x11_wrapper;
 | 
					 | 
				
			||||||
    pa_x11_client *x11_client;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const char* const valid_modargs[] = {
 | 
					static const char* const valid_modargs[] = {
 | 
				
			||||||
    "sink",
 | 
					    "sink",
 | 
				
			||||||
    "sample",
 | 
					    "sample",
 | 
				
			||||||
| 
						 | 
					@ -67,7 +57,20 @@ static const char* const valid_modargs[] = {
 | 
				
			||||||
    NULL
 | 
					    NULL
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int x11_event_callback(pa_x11_wrapper *w, XEvent *e, void *userdata) {
 | 
					struct userdata {
 | 
				
			||||||
 | 
					    pa_core *core;
 | 
				
			||||||
 | 
					    pa_module *module;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int xkb_event_base;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    char *sink_name;
 | 
				
			||||||
 | 
					    char *scache_item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pa_x11_wrapper *x11_wrapper;
 | 
				
			||||||
 | 
					    pa_x11_client *x11_client;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int x11_event_cb(pa_x11_wrapper *w, XEvent *e, void *userdata) {
 | 
				
			||||||
    XkbBellNotifyEvent *bne;
 | 
					    XkbBellNotifyEvent *bne;
 | 
				
			||||||
    struct userdata *u = userdata;
 | 
					    struct userdata *u = userdata;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -89,6 +92,25 @@ static int x11_event_callback(pa_x11_wrapper *w, XEvent *e, void *userdata) {
 | 
				
			||||||
    return 1;
 | 
					    return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (u->x11_client)
 | 
				
			||||||
 | 
					        pa_x11_client_free(u->x11_client);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (u->x11_wrapper)
 | 
				
			||||||
 | 
					        pa_x11_wrapper_unref(u->x11_wrapper);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    u->x11_client = NULL;
 | 
				
			||||||
 | 
					    u->x11_wrapper = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pa_module_unload_request(u->module);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int pa__init(pa_module*m) {
 | 
					int pa__init(pa_module*m) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct userdata *u = NULL;
 | 
					    struct userdata *u = NULL;
 | 
				
			||||||
| 
						 | 
					@ -105,7 +127,8 @@ int pa__init(pa_module*m) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    m->userdata = u = pa_xnew(struct userdata, 1);
 | 
					    m->userdata = u = pa_xnew(struct userdata, 1);
 | 
				
			||||||
    u->core = m->core;
 | 
					    u->core = m->core;
 | 
				
			||||||
    u->scache_item = pa_xstrdup(pa_modargs_get_value(ma, "sample", "x11-bell"));
 | 
					    u->module = m;
 | 
				
			||||||
 | 
					    u->scache_item = pa_xstrdup(pa_modargs_get_value(ma, "sample", "bell-window-system"));
 | 
				
			||||||
    u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));
 | 
					    u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));
 | 
				
			||||||
    u->x11_client = NULL;
 | 
					    u->x11_client = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -133,7 +156,7 @@ int pa__init(pa_module*m) {
 | 
				
			||||||
    XkbSetAutoResetControls(pa_x11_wrapper_get_display(u->x11_wrapper), XkbAudibleBellMask, &auto_ctrls, &auto_values);
 | 
					    XkbSetAutoResetControls(pa_x11_wrapper_get_display(u->x11_wrapper), XkbAudibleBellMask, &auto_ctrls, &auto_values);
 | 
				
			||||||
    XkbChangeEnabledControls(pa_x11_wrapper_get_display(u->x11_wrapper), XkbUseCoreKbd, XkbAudibleBellMask, 0);
 | 
					    XkbChangeEnabledControls(pa_x11_wrapper_get_display(u->x11_wrapper), XkbUseCoreKbd, XkbAudibleBellMask, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    u->x11_client = pa_x11_client_new(u->x11_wrapper, x11_event_callback, u);
 | 
					    u->x11_client = pa_x11_client_new(u->x11_wrapper, x11_event_cb, x11_kill_cb, u);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_modargs_free(ma);
 | 
					    pa_modargs_free(ma);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -153,11 +176,9 @@ void pa__done(pa_module*m) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_assert(m);
 | 
					    pa_assert(m);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!m->userdata)
 | 
					    if (!(u = m->userdata))
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    u = m->userdata;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pa_xfree(u->scache_item);
 | 
					    pa_xfree(u->scache_item);
 | 
				
			||||||
    pa_xfree(u->sink_name);
 | 
					    pa_xfree(u->sink_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,7 +54,7 @@
 | 
				
			||||||
#include "module-x11-publish-symdef.h"
 | 
					#include "module-x11-publish-symdef.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PA_MODULE_AUTHOR("Lennart Poettering");
 | 
					PA_MODULE_AUTHOR("Lennart Poettering");
 | 
				
			||||||
PA_MODULE_DESCRIPTION("X11 Credential Publisher");
 | 
					PA_MODULE_DESCRIPTION("X11 credential publisher");
 | 
				
			||||||
PA_MODULE_VERSION(PACKAGE_VERSION);
 | 
					PA_MODULE_VERSION(PACKAGE_VERSION);
 | 
				
			||||||
PA_MODULE_LOAD_ONCE(FALSE);
 | 
					PA_MODULE_LOAD_ONCE(FALSE);
 | 
				
			||||||
PA_MODULE_USAGE("display=<X11 display>");
 | 
					PA_MODULE_USAGE("display=<X11 display>");
 | 
				
			||||||
| 
						 | 
					@ -69,16 +69,39 @@ static const char* const valid_modargs[] = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct userdata {
 | 
					struct userdata {
 | 
				
			||||||
    pa_core *core;
 | 
					    pa_core *core;
 | 
				
			||||||
    pa_x11_wrapper *x11_wrapper;
 | 
					    pa_module *module;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    char *id;
 | 
					    char *id;
 | 
				
			||||||
    uint8_t auth_cookie[PA_NATIVE_COOKIE_LENGTH];
 | 
					    uint8_t auth_cookie[PA_NATIVE_COOKIE_LENGTH];
 | 
				
			||||||
    int auth_cookie_in_property;
 | 
					    pa_bool_t auth_cookie_in_property;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (u->x11_client)
 | 
				
			||||||
 | 
					        pa_x11_client_free(u->x11_client);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (u->x11_wrapper)
 | 
				
			||||||
 | 
					        pa_x11_wrapper_unref(u->x11_wrapper);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    u->x11_client = NULL;
 | 
				
			||||||
 | 
					    u->x11_wrapper = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pa_module_unload_request(u->module);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int load_key(struct userdata *u, const char*fn) {
 | 
					static int load_key(struct userdata *u, const char*fn) {
 | 
				
			||||||
    pa_assert(u);
 | 
					    pa_assert(u);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    u->auth_cookie_in_property = 0;
 | 
					    u->auth_cookie_in_property = FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!fn && pa_authkey_prop_get(u->core, PA_NATIVE_COOKIE_PROPERTY_NAME, u->auth_cookie, sizeof(u->auth_cookie)) >= 0) {
 | 
					    if (!fn && pa_authkey_prop_get(u->core, PA_NATIVE_COOKIE_PROPERTY_NAME, u->auth_cookie, sizeof(u->auth_cookie)) >= 0) {
 | 
				
			||||||
        pa_log_debug("using already loaded auth cookie.");
 | 
					        pa_log_debug("using already loaded auth cookie.");
 | 
				
			||||||
| 
						 | 
					@ -96,7 +119,7 @@ static int load_key(struct userdata *u, const char*fn) {
 | 
				
			||||||
    pa_log_debug("Loading cookie from disk.");
 | 
					    pa_log_debug("Loading cookie from disk.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (pa_authkey_prop_put(u->core, PA_NATIVE_COOKIE_PROPERTY_NAME, u->auth_cookie, sizeof(u->auth_cookie)) >= 0)
 | 
					    if (pa_authkey_prop_put(u->core, PA_NATIVE_COOKIE_PROPERTY_NAME, u->auth_cookie, sizeof(u->auth_cookie)) >= 0)
 | 
				
			||||||
        u->auth_cookie_in_property = 1;
 | 
					        u->auth_cookie_in_property = TRUE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -117,10 +140,13 @@ int pa__init(pa_module*m) {
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    m->userdata = u = pa_xmalloc(sizeof(struct userdata));
 | 
					    m->userdata = u = pa_xnew(struct userdata, 1);
 | 
				
			||||||
    u->core = m->core;
 | 
					    u->core = m->core;
 | 
				
			||||||
 | 
					    u->module = m;
 | 
				
			||||||
    u->id = NULL;
 | 
					    u->id = NULL;
 | 
				
			||||||
    u->auth_cookie_in_property = 0;
 | 
					    u->auth_cookie_in_property = FALSE;
 | 
				
			||||||
 | 
					    u->x11_client = NULL;
 | 
				
			||||||
 | 
					    u->x11_wrapper = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (load_key(u, pa_modargs_get_value(ma, "cookie", NULL)) < 0)
 | 
					    if (load_key(u, pa_modargs_get_value(ma, "cookie", NULL)) < 0)
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
| 
						 | 
					@ -152,7 +178,10 @@ int pa__init(pa_module*m) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_x11_set_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_COOKIE", pa_hexstr(u->auth_cookie, sizeof(u->auth_cookie), hx, sizeof(hx)));
 | 
					    pa_x11_set_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_COOKIE", pa_hexstr(u->auth_cookie, sizeof(u->auth_cookie), hx, sizeof(hx)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    u->x11_client = pa_x11_client_new(u->x11_wrapper, NULL, x11_kill_cb, u);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_modargs_free(ma);
 | 
					    pa_modargs_free(ma);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fail:
 | 
					fail:
 | 
				
			||||||
| 
						 | 
					@ -160,6 +189,7 @@ fail:
 | 
				
			||||||
        pa_modargs_free(ma);
 | 
					        pa_modargs_free(ma);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa__done(m);
 | 
					    pa__done(m);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return -1;
 | 
					    return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -171,6 +201,9 @@ void pa__done(pa_module*m) {
 | 
				
			||||||
    if (!(u = m->userdata))
 | 
					    if (!(u = m->userdata))
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (u->x11_client)
 | 
				
			||||||
 | 
					        pa_x11_client_free(u->x11_client);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (u->x11_wrapper) {
 | 
					    if (u->x11_wrapper) {
 | 
				
			||||||
        char t[256];
 | 
					        char t[256];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -185,10 +218,9 @@ void pa__done(pa_module*m) {
 | 
				
			||||||
            pa_x11_del_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_COOKIE");
 | 
					            pa_x11_del_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_COOKIE");
 | 
				
			||||||
            XSync(pa_x11_wrapper_get_display(u->x11_wrapper), False);
 | 
					            XSync(pa_x11_wrapper_get_display(u->x11_wrapper), False);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (u->x11_wrapper)
 | 
					 | 
				
			||||||
        pa_x11_wrapper_unref(u->x11_wrapper);
 | 
					        pa_x11_wrapper_unref(u->x11_wrapper);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (u->auth_cookie_in_property)
 | 
					    if (u->auth_cookie_in_property)
 | 
				
			||||||
        pa_authkey_prop_unref(m->core, PA_NATIVE_COOKIE_PROPERTY_NAME);
 | 
					        pa_authkey_prop_unref(m->core, PA_NATIVE_COOKIE_PROPERTY_NAME);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,6 +42,7 @@
 | 
				
			||||||
#include <pulsecore/namereg.h>
 | 
					#include <pulsecore/namereg.h>
 | 
				
			||||||
#include <pulsecore/log.h>
 | 
					#include <pulsecore/log.h>
 | 
				
			||||||
#include <pulsecore/core-util.h>
 | 
					#include <pulsecore/core-util.h>
 | 
				
			||||||
 | 
					#include <pulsecore/x11wrap.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "module-x11-xsmp-symdef.h"
 | 
					#include "module-x11-xsmp-symdef.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,20 +50,37 @@ PA_MODULE_AUTHOR("Lennart Poettering");
 | 
				
			||||||
PA_MODULE_DESCRIPTION("X11 session management");
 | 
					PA_MODULE_DESCRIPTION("X11 session management");
 | 
				
			||||||
PA_MODULE_VERSION(PACKAGE_VERSION);
 | 
					PA_MODULE_VERSION(PACKAGE_VERSION);
 | 
				
			||||||
PA_MODULE_LOAD_ONCE(TRUE);
 | 
					PA_MODULE_LOAD_ONCE(TRUE);
 | 
				
			||||||
 | 
					PA_MODULE_USAGE("session_manager=<session manager string> display=<X11 display>");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int ice_in_use = 0;
 | 
					
 | 
				
			||||||
 | 
					static pa_bool_t ice_in_use = FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char* const valid_modargs[] = {
 | 
					static const char* const valid_modargs[] = {
 | 
				
			||||||
 | 
					    "session_manager",
 | 
				
			||||||
 | 
					    "display",
 | 
				
			||||||
    NULL
 | 
					    NULL
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct userdata {
 | 
				
			||||||
 | 
					    pa_core *core;
 | 
				
			||||||
 | 
					    pa_module *module;
 | 
				
			||||||
 | 
					    pa_client *client;
 | 
				
			||||||
 | 
					    SmcConn connection;
 | 
				
			||||||
 | 
					    pa_x11_wrapper *x11;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void die_cb(SmcConn connection, SmPointer client_data){
 | 
					static void die_cb(SmcConn connection, SmPointer client_data){
 | 
				
			||||||
    pa_core *c = PA_CORE(client_data);
 | 
					    struct userdata *u = client_data;
 | 
				
			||||||
 | 
					    pa_assert(u);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_log_debug("Got die message from XSM. Exiting...");
 | 
					    pa_log_debug("Got die message from XSMP.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_core_assert_ref(c);
 | 
					    pa_x11_wrapper_kill(u->x11);
 | 
				
			||||||
    c->mainloop->quit(c->mainloop, 0);
 | 
					
 | 
				
			||||||
 | 
					    pa_x11_wrapper_unref(u->x11);
 | 
				
			||||||
 | 
					    u->x11 = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pa_module_unload_request(u->module);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void save_complete_cb(SmcConn connection, SmPointer client_data) {
 | 
					static void save_complete_cb(SmcConn connection, SmPointer client_data) {
 | 
				
			||||||
| 
						 | 
					@ -86,12 +104,15 @@ static void ice_io_cb(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_event_fla
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void new_ice_connection(IceConn connection, IcePointer client_data, Bool opening, IcePointer *watch_data) {
 | 
					static void new_ice_connection(IceConn connection, IcePointer client_data, Bool opening, IcePointer *watch_data) {
 | 
				
			||||||
    pa_core *c = client_data;
 | 
					    struct pa_core *c = client_data;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    pa_assert(c);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (opening)
 | 
					    if (opening)
 | 
				
			||||||
        *watch_data = c->mainloop->io_new(c->mainloop, IceConnectionNumber(connection), PA_IO_EVENT_INPUT, ice_io_cb, connection);
 | 
					        *watch_data = c->mainloop->io_new(
 | 
				
			||||||
 | 
					                c->mainloop,
 | 
				
			||||||
 | 
					                IceConnectionNumber(connection),
 | 
				
			||||||
 | 
					                PA_IO_EVENT_INPUT,
 | 
				
			||||||
 | 
					                ice_io_cb,
 | 
				
			||||||
 | 
					                connection);
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        c->mainloop->io_free(*watch_data);
 | 
					        c->mainloop->io_free(*watch_data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -99,12 +120,13 @@ static void new_ice_connection(IceConn connection, IcePointer client_data, Bool
 | 
				
			||||||
int pa__init(pa_module*m) {
 | 
					int pa__init(pa_module*m) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_modargs *ma = NULL;
 | 
					    pa_modargs *ma = NULL;
 | 
				
			||||||
    char t[256], *vendor, *client_id;
 | 
					    char t[256], *vendor, *client_id, *k;
 | 
				
			||||||
    SmcCallbacks callbacks;
 | 
					    SmcCallbacks callbacks;
 | 
				
			||||||
    SmProp prop_program, prop_user;
 | 
					    SmProp prop_program, prop_user;
 | 
				
			||||||
    SmProp *prop_list[2];
 | 
					    SmProp *prop_list[2];
 | 
				
			||||||
    SmPropValue val_program, val_user;
 | 
					    SmPropValue val_program, val_user;
 | 
				
			||||||
    SmcConn connection;
 | 
					    struct userdata *u;
 | 
				
			||||||
 | 
					    const char *e;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_assert(m);
 | 
					    pa_assert(m);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -114,21 +136,33 @@ int pa__init(pa_module*m) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    IceAddConnectionWatch(new_ice_connection, m->core);
 | 
					    IceAddConnectionWatch(new_ice_connection, m->core);
 | 
				
			||||||
    ice_in_use = 1;
 | 
					    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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
 | 
					    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
 | 
				
			||||||
        pa_log("Failed to parse module arguments");
 | 
					        pa_log("Failed to parse module arguments");
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!getenv("SESSION_MANAGER")) {
 | 
					    if (!(u->x11 = pa_x11_wrapper_get(m->core, pa_modargs_get_value(ma, "display", NULL))))
 | 
				
			||||||
 | 
					        goto fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    e = pa_modargs_get_value(ma, "session_manager", NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!e && !getenv("SESSION_MANAGER")) {
 | 
				
			||||||
        pa_log("X11 session manager not running.");
 | 
					        pa_log("X11 session manager not running.");
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    memset(&callbacks, 0, sizeof(callbacks));
 | 
					    memset(&callbacks, 0, sizeof(callbacks));
 | 
				
			||||||
    callbacks.die.callback = die_cb;
 | 
					    callbacks.die.callback = die_cb;
 | 
				
			||||||
    callbacks.die.client_data = m->core;
 | 
					    callbacks.die.client_data = u;
 | 
				
			||||||
    callbacks.save_yourself.callback = save_yourself_cb;
 | 
					    callbacks.save_yourself.callback = save_yourself_cb;
 | 
				
			||||||
    callbacks.save_yourself.client_data = m->core;
 | 
					    callbacks.save_yourself.client_data = m->core;
 | 
				
			||||||
    callbacks.save_complete.callback = save_complete_cb;
 | 
					    callbacks.save_complete.callback = save_complete_cb;
 | 
				
			||||||
| 
						 | 
					@ -136,8 +170,8 @@ int pa__init(pa_module*m) {
 | 
				
			||||||
    callbacks.shutdown_cancelled.callback = shutdown_cancelled_cb;
 | 
					    callbacks.shutdown_cancelled.callback = shutdown_cancelled_cb;
 | 
				
			||||||
    callbacks.shutdown_cancelled.client_data = m->core;
 | 
					    callbacks.shutdown_cancelled.client_data = m->core;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!(m->userdata = connection = SmcOpenConnection(
 | 
					    if (!(u->connection = SmcOpenConnection(
 | 
				
			||||||
                  NULL, m->core,
 | 
					                  (char*) e, m->core,
 | 
				
			||||||
                  SmProtoMajor, SmProtoMinor,
 | 
					                  SmProtoMajor, SmProtoMinor,
 | 
				
			||||||
                  SmcSaveYourselfProcMask | SmcDieProcMask | SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask,
 | 
					                  SmcSaveYourselfProcMask | SmcDieProcMask | SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask,
 | 
				
			||||||
                  &callbacks, NULL, &client_id,
 | 
					                  &callbacks, NULL, &client_id,
 | 
				
			||||||
| 
						 | 
					@ -164,9 +198,16 @@ int pa__init(pa_module*m) {
 | 
				
			||||||
    prop_user.vals = &val_user;
 | 
					    prop_user.vals = &val_user;
 | 
				
			||||||
    prop_list[1] = &prop_user;
 | 
					    prop_list[1] = &prop_user;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SmcSetProperties(connection, PA_ELEMENTSOF(prop_list), prop_list);
 | 
					    SmcSetProperties(u->connection, PA_ELEMENTSOF(prop_list), prop_list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pa_log_info("Connected to session manager '%s' as '%s'.", vendor = SmcVendor(u->connection), client_id);
 | 
				
			||||||
 | 
					    k = pa_sprintf_malloc("XSMP Session on %s as %s", vendor, client_id);
 | 
				
			||||||
 | 
					    u->client = pa_client_new(u->core, __FILE__, k);
 | 
				
			||||||
 | 
					    pa_xfree(k);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pa_proplist_sets(u->client->proplist, "xsmp.vendor", vendor);
 | 
				
			||||||
 | 
					    pa_proplist_sets(u->client->proplist, "xsmp.client.id", client_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_log_info("Connected to session manager '%s' as '%s'.", vendor = SmcVendor(connection), client_id);
 | 
					 | 
				
			||||||
    free(vendor);
 | 
					    free(vendor);
 | 
				
			||||||
    free(client_id);
 | 
					    free(client_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -184,13 +225,26 @@ fail:
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pa__done(pa_module*m) {
 | 
					void pa__done(pa_module*m) {
 | 
				
			||||||
 | 
					    struct userdata *u;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_assert(m);
 | 
					    pa_assert(m);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (m->userdata)
 | 
					    if ((u = m->userdata)) {
 | 
				
			||||||
        SmcCloseConnection(m->userdata, 0, NULL);
 | 
					
 | 
				
			||||||
 | 
					        if (u->connection)
 | 
				
			||||||
 | 
					            SmcCloseConnection(u->connection, 0, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (u->client)
 | 
				
			||||||
 | 
					            pa_client_free(u->client);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (u->x11)
 | 
				
			||||||
 | 
					            pa_x11_wrapper_unref(u->x11);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        pa_xfree(u);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (ice_in_use) {
 | 
					    if (ice_in_use) {
 | 
				
			||||||
        IceRemoveConnectionWatch(new_ice_connection, m->core);
 | 
					        IceRemoveConnectionWatch(new_ice_connection, m->core);
 | 
				
			||||||
        ice_in_use = 0;
 | 
					        ice_in_use = FALSE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,7 +63,8 @@ struct pa_x11_wrapper {
 | 
				
			||||||
struct pa_x11_client {
 | 
					struct pa_x11_client {
 | 
				
			||||||
    PA_LLIST_FIELDS(pa_x11_client);
 | 
					    PA_LLIST_FIELDS(pa_x11_client);
 | 
				
			||||||
    pa_x11_wrapper *wrapper;
 | 
					    pa_x11_wrapper *wrapper;
 | 
				
			||||||
    int (*callback)(pa_x11_wrapper *w, XEvent *e, void *userdata);
 | 
					    pa_x11_event_cb_t event_cb;
 | 
				
			||||||
 | 
					    pa_x11_kill_cb_t kill_cb;
 | 
				
			||||||
    void *userdata;
 | 
					    void *userdata;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -72,17 +73,23 @@ static void work(pa_x11_wrapper *w) {
 | 
				
			||||||
    pa_assert(w);
 | 
					    pa_assert(w);
 | 
				
			||||||
    pa_assert(PA_REFCNT_VALUE(w) >= 1);
 | 
					    pa_assert(PA_REFCNT_VALUE(w) >= 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pa_x11_wrapper_ref(w);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while (XPending(w->display)) {
 | 
					    while (XPending(w->display)) {
 | 
				
			||||||
        pa_x11_client *c;
 | 
					        pa_x11_client *c, *n;
 | 
				
			||||||
        XEvent e;
 | 
					        XEvent e;
 | 
				
			||||||
        XNextEvent(w->display, &e);
 | 
					        XNextEvent(w->display, &e);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (c = w->clients; c; c = c->next) {
 | 
					        for (c = w->clients; c; c = n) {
 | 
				
			||||||
            pa_assert(c->callback);
 | 
					            n = c->next;
 | 
				
			||||||
            if (c->callback(w, &e, c->userdata) != 0)
 | 
					
 | 
				
			||||||
                break;
 | 
					            if (c->event_cb)
 | 
				
			||||||
 | 
					                if (c->event_cb(w, &e, c->userdata) != 0)
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pa_x11_wrapper_unref(w);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* IO notification event for the X11 display connection */
 | 
					/* IO notification event for the X11 display connection */
 | 
				
			||||||
| 
						 | 
					@ -251,7 +258,24 @@ Display *pa_x11_wrapper_get_display(pa_x11_wrapper *w) {
 | 
				
			||||||
    return w->display;
 | 
					    return w->display;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pa_x11_client* pa_x11_client_new(pa_x11_wrapper *w, int (*cb)(pa_x11_wrapper *w, XEvent *e, void *userdata), void *userdata) {
 | 
					void pa_x11_wrapper_kill(pa_x11_wrapper *w) {
 | 
				
			||||||
 | 
					    pa_x11_client *c, *n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pa_assert(w);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pa_x11_wrapper_ref(w);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (c = w->clients; c; c = n) {
 | 
				
			||||||
 | 
					        n = c->next;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (c->kill_cb)
 | 
				
			||||||
 | 
					            c->kill_cb(w, c->userdata);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pa_x11_wrapper_unref(w);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pa_x11_client* pa_x11_client_new(pa_x11_wrapper *w, pa_x11_event_cb_t event_cb, pa_x11_kill_cb_t kill_cb, void *userdata) {
 | 
				
			||||||
    pa_x11_client *c;
 | 
					    pa_x11_client *c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_assert(w);
 | 
					    pa_assert(w);
 | 
				
			||||||
| 
						 | 
					@ -259,7 +283,8 @@ pa_x11_client* pa_x11_client_new(pa_x11_wrapper *w, int (*cb)(pa_x11_wrapper *w,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    c = pa_xnew(pa_x11_client, 1);
 | 
					    c = pa_xnew(pa_x11_client, 1);
 | 
				
			||||||
    c->wrapper = w;
 | 
					    c->wrapper = w;
 | 
				
			||||||
    c->callback = cb;
 | 
					    c->event_cb = event_cb;
 | 
				
			||||||
 | 
					    c->kill_cb = kill_cb;
 | 
				
			||||||
    c->userdata = userdata;
 | 
					    c->userdata = userdata;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    PA_LLIST_PREPEND(pa_x11_client, w->clients, c);
 | 
					    PA_LLIST_PREPEND(pa_x11_client, w->clients, c);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,6 +30,11 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct pa_x11_wrapper pa_x11_wrapper;
 | 
					typedef struct pa_x11_wrapper pa_x11_wrapper;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct pa_x11_client pa_x11_client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef int (*pa_x11_event_cb_t)(pa_x11_wrapper *w, XEvent *e, void *userdata);
 | 
				
			||||||
 | 
					typedef void (*pa_x11_kill_cb_t)(pa_x11_wrapper *w, void *userdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Return the X11 wrapper for this core. In case no wrapper was
 | 
					/* Return the X11 wrapper for this core. In case no wrapper was
 | 
				
			||||||
    existant before, allocate a new one */
 | 
					    existant before, allocate a new one */
 | 
				
			||||||
pa_x11_wrapper* pa_x11_wrapper_get(pa_core *c, const char *name);
 | 
					pa_x11_wrapper* pa_x11_wrapper_get(pa_core *c, const char *name);
 | 
				
			||||||
| 
						 | 
					@ -43,10 +48,11 @@ void pa_x11_wrapper_unref(pa_x11_wrapper* w);
 | 
				
			||||||
/* Return the X11 display object for this connection */
 | 
					/* Return the X11 display object for this connection */
 | 
				
			||||||
Display *pa_x11_wrapper_get_display(pa_x11_wrapper *w);
 | 
					Display *pa_x11_wrapper_get_display(pa_x11_wrapper *w);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct pa_x11_client pa_x11_client;
 | 
					/* Kill the connection to the X11 display */
 | 
				
			||||||
 | 
					void pa_x11_wrapper_kill(pa_x11_wrapper *w);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Register an X11 client, that is called for each X11 event */
 | 
					/* Register an X11 client, that is called for each X11 event */
 | 
				
			||||||
pa_x11_client* pa_x11_client_new(pa_x11_wrapper *w, int (*cb)(pa_x11_wrapper *w, XEvent *e, void *userdata), void *userdata);
 | 
					pa_x11_client* pa_x11_client_new(pa_x11_wrapper *w, pa_x11_event_cb_t event_cb, pa_x11_kill_cb_t kill_cb, void *userdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Free an X11 client object */
 | 
					/* Free an X11 client object */
 | 
				
			||||||
void pa_x11_client_free(pa_x11_client *c);
 | 
					void pa_x11_client_free(pa_x11_client *c);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue