~ubuntu-branches/ubuntu/karmic/tangerine/karmic

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <X11/SM/SMlib.h>
#include <signal.h>

static IceConn iceconn = NULL;
static int pipes[2];
static int closed = 0;

static void
session_died (SmcConn conn, SmPointer client_data)
{
	SmcCloseConnection (conn, 0, NULL);
	kill (getpid (), SIGTERM);
}

static void
save_yourself (SmcConn conn, SmPointer client_data, int save_type, Bool shutdown, int interact_style, Bool fast)
{
	SmcSaveYourselfDone (conn, True);
}

static void
save_complete (SmcConn conn, SmPointer client_data)
{
}

static void
shutdown_cancelled (SmcConn conn, SmPointer client_data)
{
}

static void
ice_watch (IceConn ice_conn, IcePointer client_data, Bool opening, IcePointer *watch_data)
{
	if (opening) {
		iceconn = ice_conn;
	}
}

void
close_session (void)
{
	if (iceconn != NULL) {
		closed = 1;
		write (pipes[1], "closed", 7);
	}
}

void
run_session (void)
{
	SmcConn conn;
	SmcCallbacks callbacks;
	char *id;
	fd_set rfds;

	IceInitThreads ();
	IceAddConnectionWatch (ice_watch, NULL);

	bzero (&callbacks, sizeof (SmcCallbacks));
	callbacks.die.callback = session_died;
	callbacks.save_yourself.callback = save_yourself;
	callbacks.save_complete.callback = save_complete;
	callbacks.shutdown_cancelled.callback = shutdown_cancelled;
	
	conn = SmcOpenConnection (NULL, NULL, 1, 0, SmcDieProcMask | SmcSaveYourselfProcMask |
				  SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask, &callbacks,
				  NULL, &id, 0, NULL);
	IceRemoveConnectionWatch (ice_watch, NULL);

	if (conn == NULL)
		return;
	
        FD_ZERO (&rfds);
        FD_SET (IceConnectionNumber (iceconn), &rfds);

	pipe (pipes);
	FD_SET (pipes[0], &rfds);
	
	
        while (select (pipes[0] + 1, &rfds, NULL, NULL, NULL) > 0) {
		if (closed) {
			SmcConn smcconn = (SmcConn) iceconn;
			if (smcconn == NULL)
				continue;
			SmcCloseConnection (smcconn, 0, NULL);
			break;
		} else if (IceProcessMessages (iceconn, NULL, NULL) == IceProcessMessagesConnectionClosed) {
			break;
		}
	}
}