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;
}
}
}
|