| 50 IceConn connection; |
50 IceConn connection; |
| 51 guint input_id; |
51 guint input_id; |
| 52 }; |
52 }; |
| 53 |
53 |
| 54 static void ice_process_messages(gpointer data, gint fd, |
54 static void ice_process_messages(gpointer data, gint fd, |
| 55 GaimInputCondition condition) { |
55 PurpleInputCondition condition) { |
| 56 struct ice_connection_info *conninfo = (struct ice_connection_info*) data; |
56 struct ice_connection_info *conninfo = (struct ice_connection_info*) data; |
| 57 IceProcessMessagesStatus status; |
57 IceProcessMessagesStatus status; |
| 58 |
58 |
| 59 /* please don't block... please! */ |
59 /* please don't block... please! */ |
| 60 status = IceProcessMessages(conninfo->connection, NULL, NULL); |
60 status = IceProcessMessages(conninfo->connection, NULL, NULL); |
| 61 |
61 |
| 62 if (status == IceProcessMessagesIOError) { |
62 if (status == IceProcessMessagesIOError) { |
| 63 gaim_debug(GAIM_DEBUG_INFO, "Session Management", |
63 purple_debug(PURPLE_DEBUG_INFO, "Session Management", |
| 64 "ICE IO error, closing connection... "); |
64 "ICE IO error, closing connection... "); |
| 65 |
65 |
| 66 /* IO error, please disconnect */ |
66 /* IO error, please disconnect */ |
| 67 IceSetShutdownNegotiation(conninfo->connection, False); |
67 IceSetShutdownNegotiation(conninfo->connection, False); |
| 68 IceCloseConnection(conninfo->connection); |
68 IceCloseConnection(conninfo->connection); |
| 69 |
69 |
| 70 gaim_debug(GAIM_DEBUG_INFO, NULL, "done.\n"); |
70 purple_debug(PURPLE_DEBUG_INFO, NULL, "done.\n"); |
| 71 |
71 |
| 72 /* cancel the handler */ |
72 /* cancel the handler */ |
| 73 gaim_input_remove(conninfo->input_id); |
73 purple_input_remove(conninfo->input_id); |
| 74 } |
74 } |
| 75 } |
75 } |
| 76 |
76 |
| 77 static void ice_connection_watch(IceConn connection, IcePointer client_data, |
77 static void ice_connection_watch(IceConn connection, IcePointer client_data, |
| 78 Bool opening, IcePointer *watch_data) { |
78 Bool opening, IcePointer *watch_data) { |
| 79 struct ice_connection_info *conninfo = NULL; |
79 struct ice_connection_info *conninfo = NULL; |
| 80 |
80 |
| 81 if (opening) { |
81 if (opening) { |
| 82 gaim_debug(GAIM_DEBUG_INFO, "Session Management", |
82 purple_debug(PURPLE_DEBUG_INFO, "Session Management", |
| 83 "Handling new ICE connection... "); |
83 "Handling new ICE connection... "); |
| 84 |
84 |
| 85 /* ensure ICE connection is not passed to child processes */ |
85 /* ensure ICE connection is not passed to child processes */ |
| 86 fcntl(IceConnectionNumber(connection), F_SETFD, FD_CLOEXEC); |
86 fcntl(IceConnectionNumber(connection), F_SETFD, FD_CLOEXEC); |
| 87 |
87 |
| 88 conninfo = g_new(struct ice_connection_info, 1); |
88 conninfo = g_new(struct ice_connection_info, 1); |
| 89 conninfo->connection = connection; |
89 conninfo->connection = connection; |
| 90 |
90 |
| 91 /* watch the connection */ |
91 /* watch the connection */ |
| 92 conninfo->input_id = gaim_input_add(IceConnectionNumber(connection), GAIM_INPUT_READ, |
92 conninfo->input_id = purple_input_add(IceConnectionNumber(connection), PURPLE_INPUT_READ, |
| 93 ice_process_messages, conninfo); |
93 ice_process_messages, conninfo); |
| 94 *watch_data = conninfo; |
94 *watch_data = conninfo; |
| 95 } else { |
95 } else { |
| 96 gaim_debug(GAIM_DEBUG_INFO, "Session Management", |
96 purple_debug(PURPLE_DEBUG_INFO, "Session Management", |
| 97 "Handling closed ICE connection... "); |
97 "Handling closed ICE connection... "); |
| 98 |
98 |
| 99 /* get the input ID back and stop watching it */ |
99 /* get the input ID back and stop watching it */ |
| 100 conninfo = (struct ice_connection_info*) *watch_data; |
100 conninfo = (struct ice_connection_info*) *watch_data; |
| 101 gaim_input_remove(conninfo->input_id); |
101 purple_input_remove(conninfo->input_id); |
| 102 g_free(conninfo); |
102 g_free(conninfo); |
| 103 } |
103 } |
| 104 |
104 |
| 105 gaim_debug(GAIM_DEBUG_INFO, NULL, "done.\n"); |
105 purple_debug(PURPLE_DEBUG_INFO, NULL, "done.\n"); |
| 106 } |
106 } |
| 107 |
107 |
| 108 /* We call any handler installed before (or after) ice_init but |
108 /* We call any handler installed before (or after) ice_init but |
| 109 * avoid calling the default libICE handler which does an exit(). |
109 * avoid calling the default libICE handler which does an exit(). |
| 110 * |
110 * |
| 111 * This means we do nothing by default, which is probably correct, |
111 * This means we do nothing by default, which is probably correct, |
| 112 * the connection will get closed by libICE |
112 * the connection will get closed by libICE |
| 113 */ |
113 */ |
| 114 |
114 |
| 115 static void ice_io_error_handler(IceConn connection) { |
115 static void ice_io_error_handler(IceConn connection) { |
| 116 gaim_debug(GAIM_DEBUG_INFO, "Session Management", |
116 purple_debug(PURPLE_DEBUG_INFO, "Session Management", |
| 117 "Handling ICE IO error... "); |
117 "Handling ICE IO error... "); |
| 118 |
118 |
| 119 if (ice_installed_io_error_handler) |
119 if (ice_installed_io_error_handler) |
| 120 (*ice_installed_io_error_handler)(connection); |
120 (*ice_installed_io_error_handler)(connection); |
| 121 |
121 |
| 122 gaim_debug(GAIM_DEBUG_INFO, NULL, "done.\n"); |
122 purple_debug(PURPLE_DEBUG_INFO, NULL, "done.\n"); |
| 123 } |
123 } |
| 124 |
124 |
| 125 static void ice_init() { |
125 static void ice_init() { |
| 126 IceIOErrorHandler default_handler; |
126 IceIOErrorHandler default_handler; |
| 127 |
127 |
| 171 Bool shutdown, int interact_style, Bool fast) { |
171 Bool shutdown, int interact_style, Bool fast) { |
| 172 if (had_first_save == FALSE && save_type == SmSaveLocal && |
172 if (had_first_save == FALSE && save_type == SmSaveLocal && |
| 173 interact_style == SmInteractStyleNone && !shutdown && |
173 interact_style == SmInteractStyleNone && !shutdown && |
| 174 !fast) { |
174 !fast) { |
| 175 /* this is just a dry run, spit it back */ |
175 /* this is just a dry run, spit it back */ |
| 176 gaim_debug(GAIM_DEBUG_INFO, "Session Management", |
176 purple_debug(PURPLE_DEBUG_INFO, "Session Management", |
| 177 "Received first save_yourself\n"); |
177 "Received first save_yourself\n"); |
| 178 SmcSaveYourselfDone(conn, True); |
178 SmcSaveYourselfDone(conn, True); |
| 179 had_first_save = TRUE; |
179 had_first_save = TRUE; |
| 180 return; |
180 return; |
| 181 } |
181 } |
| 182 |
182 |
| 183 /* tum ti tum... don't add anything else here without * |
183 /* tum ti tum... don't add anything else here without * |
| 184 * reading SMlib.PS from an X.org ftp server near you */ |
184 * reading SMlib.PS from an X.org ftp server near you */ |
| 185 |
185 |
| 186 gaim_debug(GAIM_DEBUG_INFO, "Session Management", |
186 purple_debug(PURPLE_DEBUG_INFO, "Session Management", |
| 187 "Received save_yourself\n"); |
187 "Received save_yourself\n"); |
| 188 |
188 |
| 189 if (save_type == SmSaveGlobal || save_type == SmSaveBoth) { |
189 if (save_type == SmSaveGlobal || save_type == SmSaveBoth) { |
| 190 /* may as well do something ... */ |
190 /* may as well do something ... */ |
| 191 /* or not -- save_prefs(); */ |
191 /* or not -- save_prefs(); */ |
| 193 |
193 |
| 194 SmcSaveYourselfDone(conn, True); |
194 SmcSaveYourselfDone(conn, True); |
| 195 } |
195 } |
| 196 |
196 |
| 197 static void session_die(SmcConn conn, SmPointer data) { |
197 static void session_die(SmcConn conn, SmPointer data) { |
| 198 gaim_debug(GAIM_DEBUG_INFO, "Session Management", |
198 purple_debug(PURPLE_DEBUG_INFO, "Session Management", |
| 199 "Received die\n"); |
199 "Received die\n"); |
| 200 gaim_core_quit(); |
200 purple_core_quit(); |
| 201 } |
201 } |
| 202 |
202 |
| 203 static void session_save_complete(SmcConn conn, SmPointer data) { |
203 static void session_save_complete(SmcConn conn, SmPointer data) { |
| 204 gaim_debug(GAIM_DEBUG_INFO, "Session Management", |
204 purple_debug(PURPLE_DEBUG_INFO, "Session Management", |
| 205 "Received save_complete\n"); |
205 "Received save_complete\n"); |
| 206 } |
206 } |
| 207 |
207 |
| 208 static void session_shutdown_cancelled(SmcConn conn, SmPointer data) { |
208 static void session_shutdown_cancelled(SmcConn conn, SmPointer data) { |
| 209 gaim_debug(GAIM_DEBUG_INFO, "Session Management", |
209 purple_debug(PURPLE_DEBUG_INFO, "Session Management", |
| 210 "Received shutdown_cancelled\n"); |
210 "Received shutdown_cancelled\n"); |
| 211 } |
211 } |
| 212 |
212 |
| 213 /* utility functions stolen from Gnome-client */ |
213 /* utility functions stolen from Gnome-client */ |
| 214 |
214 |
| 312 callbacks.die.client_data = NULL; |
312 callbacks.die.client_data = NULL; |
| 313 callbacks.save_complete.client_data = NULL; |
313 callbacks.save_complete.client_data = NULL; |
| 314 callbacks.shutdown_cancelled.client_data = NULL; |
314 callbacks.shutdown_cancelled.client_data = NULL; |
| 315 |
315 |
| 316 if (previous_id) { |
316 if (previous_id) { |
| 317 gaim_debug(GAIM_DEBUG_INFO, "Session Management", |
317 purple_debug(PURPLE_DEBUG_INFO, "Session Management", |
| 318 "Connecting with previous ID %s\n", previous_id); |
318 "Connecting with previous ID %s\n", previous_id); |
| 319 } else { |
319 } else { |
| 320 gaim_debug(GAIM_DEBUG_INFO, "Session Management", |
320 purple_debug(PURPLE_DEBUG_INFO, "Session Management", |
| 321 "Connecting with no previous ID\n"); |
321 "Connecting with no previous ID\n"); |
| 322 } |
322 } |
| 323 |
323 |
| 324 session = SmcOpenConnection(NULL, "session", SmProtoMajor, SmProtoMinor, SmcSaveYourselfProcMask | |
324 session = SmcOpenConnection(NULL, "session", SmProtoMajor, SmProtoMinor, SmcSaveYourselfProcMask | |
| 325 SmcDieProcMask | SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask, |
325 SmcDieProcMask | SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask, |
| 326 &callbacks, previous_id, &client_id, ERROR_LENGTH, error); |
326 &callbacks, previous_id, &client_id, ERROR_LENGTH, error); |
| 327 |
327 |
| 328 if (session == NULL) { |
328 if (session == NULL) { |
| 329 if (error[0] != '\0') { |
329 if (error[0] != '\0') { |
| 330 gaim_debug(GAIM_DEBUG_ERROR, "Session Management", |
330 purple_debug(PURPLE_DEBUG_ERROR, "Session Management", |
| 331 "Connection failed with error: %s\n", error); |
331 "Connection failed with error: %s\n", error); |
| 332 } else { |
332 } else { |
| 333 gaim_debug(GAIM_DEBUG_ERROR, "Session Management", |
333 purple_debug(PURPLE_DEBUG_ERROR, "Session Management", |
| 334 "Connetion failed with unknown error.\n"); |
334 "Connetion failed with unknown error.\n"); |
| 335 } |
335 } |
| 336 return; |
336 return; |
| 337 } |
337 } |
| 338 |
338 |
| 339 tmp = SmcVendor(session); |
339 tmp = SmcVendor(session); |
| 340 gaim_debug(GAIM_DEBUG_INFO, "Session Management", |
340 purple_debug(PURPLE_DEBUG_INFO, "Session Management", |
| 341 "Connected to manager (%s) with client ID %s\n", |
341 "Connected to manager (%s) with client ID %s\n", |
| 342 tmp, client_id); |
342 tmp, client_id); |
| 343 g_free(tmp); |
343 g_free(tmp); |
| 344 |
344 |
| 345 session_managed = TRUE; |
345 session_managed = TRUE; |