sm_client.c revision 3c15da26
1126a8a12Smrg/* 2126a8a12Smrg 3126a8a12SmrgCopyright 1993, 1998 The Open Group 4126a8a12Smrg 5126a8a12SmrgPermission to use, copy, modify, distribute, and sell this software and its 6126a8a12Smrgdocumentation for any purpose is hereby granted without fee, provided that 7126a8a12Smrgthe above copyright notice appear in all copies and that both that 8126a8a12Smrgcopyright notice and this permission notice appear in supporting 9126a8a12Smrgdocumentation. 10126a8a12Smrg 11126a8a12SmrgThe above copyright notice and this permission notice shall be included in 12126a8a12Smrgall copies or substantial portions of the Software. 13126a8a12Smrg 14126a8a12SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15126a8a12SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16126a8a12SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17126a8a12SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18126a8a12SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19126a8a12SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20126a8a12Smrg 21126a8a12SmrgExcept as contained in this notice, the name of The Open Group shall not be 22126a8a12Smrgused in advertising or otherwise to promote the sale, use or other dealings 23126a8a12Smrgin this Software without prior written authorization from The Open Group. 24126a8a12Smrg 25126a8a12Smrg*/ 26126a8a12Smrg 27126a8a12Smrg/* 28126a8a12Smrg * Author: Ralph Mor, X Consortium 29126a8a12Smrg */ 30126a8a12Smrg 31126a8a12Smrg#ifdef HAVE_CONFIG_H 32126a8a12Smrg#include <config.h> 33126a8a12Smrg#endif 34126a8a12Smrg#include <X11/SM/SMlib.h> 35126a8a12Smrg#include "SMlibint.h" 36126a8a12Smrg 37d656433aSmrgint _SmcOpcode = 0; 38d656433aSmrgint _SmsOpcode = 0; 39d656433aSmrg 40d656433aSmrg#ifndef __UNIXOS2__ 41d656433aSmrgSmsNewClientProc _SmsNewClientProc; 42d656433aSmrgSmPointer _SmsNewClientData; 43d656433aSmrg#else 44d656433aSmrgSmsNewClientProc _SmsNewClientProc = 0; 45d656433aSmrgSmPointer _SmsNewClientData = 0; 46d656433aSmrg#endif 47d656433aSmrg 48d656433aSmrgSmcErrorHandler _SmcErrorHandler = _SmcDefaultErrorHandler; 49d656433aSmrgSmsErrorHandler _SmsErrorHandler = _SmsDefaultErrorHandler; 50d656433aSmrg 51d656433aSmrg 52d656433aSmrgstatic void 53d656433aSmrgset_callbacks(SmcConn smcConn, unsigned long mask, SmcCallbacks *callbacks); 54126a8a12Smrg 55126a8a12Smrg 56126a8a12SmrgSmcConn 57d656433aSmrgSmcOpenConnection(char *networkIdsList, SmPointer context, 58d656433aSmrg int xsmpMajorRev, int xsmpMinorRev, 59d656433aSmrg unsigned long mask, SmcCallbacks *callbacks, 60d656433aSmrg char *previousId, char **clientIdRet, 61d656433aSmrg int errorLength, char *errorStringRet) 62126a8a12Smrg{ 63126a8a12Smrg SmcConn smcConn; 64126a8a12Smrg IceConn iceConn; 65126a8a12Smrg char *ids; 66126a8a12Smrg IceProtocolSetupStatus setupstat; 67126a8a12Smrg int majorVersion; 68126a8a12Smrg int minorVersion; 69126a8a12Smrg char *vendor = NULL; 70126a8a12Smrg char *release = NULL; 71126a8a12Smrg smRegisterClientMsg *pMsg; 72126a8a12Smrg char *pData; 73126a8a12Smrg int extra, len; 74126a8a12Smrg IceReplyWaitInfo replyWait; 75126a8a12Smrg _SmcRegisterClientReply reply; 76126a8a12Smrg Bool gotReply, ioErrorOccured; 77126a8a12Smrg 78126a8a12Smrg const char *auth_names[] = {"MIT-MAGIC-COOKIE-1"}; 79126a8a12Smrg IcePoAuthProc auth_procs[] = {_IcePoMagicCookie1Proc}; 80126a8a12Smrg int auth_count = 1; 81126a8a12Smrg 82126a8a12Smrg IcePoVersionRec versions[] = { 83126a8a12Smrg {SmProtoMajor, SmProtoMinor, _SmcProcessMessage} 84126a8a12Smrg }; 85126a8a12Smrg int version_count = 1; 86126a8a12Smrg 87126a8a12Smrg 88126a8a12Smrg *clientIdRet = NULL; 89126a8a12Smrg 90126a8a12Smrg if (errorStringRet && errorLength > 0) 91126a8a12Smrg *errorStringRet = '\0'; 92126a8a12Smrg 93126a8a12Smrg if (!_SmcOpcode) 94126a8a12Smrg { 95126a8a12Smrg /* 96126a8a12Smrg * For now, there is only one version of XSMP, so we don't 97126a8a12Smrg * have to check {xsmpMajorRev, xsmpMinorRev}. In the future, 98126a8a12Smrg * we will check against versions and generate the list 99126a8a12Smrg * of versions the application actually supports. 100126a8a12Smrg */ 101126a8a12Smrg 102126a8a12Smrg if ((_SmcOpcode = IceRegisterForProtocolSetup ("XSMP", 103126a8a12Smrg SmVendorString, SmReleaseString, version_count, versions, 104126a8a12Smrg auth_count, auth_names, auth_procs, NULL)) < 0) 105126a8a12Smrg { 106126a8a12Smrg if (errorStringRet && errorLength > 0) { 107126a8a12Smrg strncpy (errorStringRet, 108126a8a12Smrg "Could not register XSMP protocol with ICE", 109126a8a12Smrg errorLength); 110126a8a12Smrg errorStringRet[errorLength - 1] = '\0'; 111126a8a12Smrg } 112126a8a12Smrg 113126a8a12Smrg return (NULL); 114126a8a12Smrg } 115126a8a12Smrg } 116126a8a12Smrg 117126a8a12Smrg if (networkIdsList == NULL || *networkIdsList == '\0') 118126a8a12Smrg { 119126a8a12Smrg if ((ids = (char *) getenv ("SESSION_MANAGER")) == NULL) 120126a8a12Smrg { 121126a8a12Smrg if (errorStringRet && errorLength > 0) { 122126a8a12Smrg strncpy (errorStringRet, 123126a8a12Smrg "SESSION_MANAGER environment variable not defined", 124126a8a12Smrg errorLength); 125126a8a12Smrg errorStringRet[errorLength - 1] = '\0'; 126126a8a12Smrg } 127126a8a12Smrg return (NULL); 128126a8a12Smrg } 129126a8a12Smrg } 130126a8a12Smrg else 131126a8a12Smrg { 132126a8a12Smrg ids = networkIdsList; 133126a8a12Smrg } 134126a8a12Smrg 135126a8a12Smrg if ((iceConn = IceOpenConnection ( 136126a8a12Smrg ids, context, 0, _SmcOpcode, errorLength, errorStringRet)) == NULL) 137126a8a12Smrg { 138126a8a12Smrg return (NULL); 139126a8a12Smrg } 140126a8a12Smrg 1413c15da26Smrg if ((smcConn = malloc (sizeof (struct _SmcConn))) == NULL) 142126a8a12Smrg { 143126a8a12Smrg if (errorStringRet && errorLength > 0) { 144126a8a12Smrg strncpy (errorStringRet, "Can't malloc", errorLength); 145126a8a12Smrg errorStringRet[errorLength - 1] = '\0'; 146126a8a12Smrg } 147126a8a12Smrg IceCloseConnection (iceConn); 148126a8a12Smrg return (NULL); 149126a8a12Smrg } 150126a8a12Smrg 151126a8a12Smrg setupstat = IceProtocolSetup (iceConn, _SmcOpcode, 152126a8a12Smrg (IcePointer) smcConn, 153126a8a12Smrg False /* mustAuthenticate */, 154126a8a12Smrg &majorVersion, &minorVersion, 155126a8a12Smrg &vendor, &release, errorLength, errorStringRet); 156126a8a12Smrg 157126a8a12Smrg if (setupstat == IceProtocolSetupFailure || 158126a8a12Smrg setupstat == IceProtocolSetupIOError) 159126a8a12Smrg { 160126a8a12Smrg IceCloseConnection (iceConn); 1613c15da26Smrg free (smcConn); 162126a8a12Smrg return (NULL); 163126a8a12Smrg } 164126a8a12Smrg else if (setupstat == IceProtocolAlreadyActive) 165126a8a12Smrg { 166126a8a12Smrg /* 167126a8a12Smrg * This case should never happen, because when we called 168126a8a12Smrg * IceOpenConnection, we required that the ICE connection 169126a8a12Smrg * may not already have XSMP active on it. 170126a8a12Smrg */ 171126a8a12Smrg 1723c15da26Smrg free (smcConn); 173126a8a12Smrg if (errorStringRet && errorLength > 0) { 174126a8a12Smrg strncpy (errorStringRet, "Internal error in IceOpenConnection", 175126a8a12Smrg errorLength); 176126a8a12Smrg errorStringRet[errorLength - 1] = '\0'; 177126a8a12Smrg } 178126a8a12Smrg return (NULL); 179126a8a12Smrg } 180126a8a12Smrg 181126a8a12Smrg smcConn->iceConn = iceConn; 182126a8a12Smrg smcConn->proto_major_version = majorVersion; 183126a8a12Smrg smcConn->proto_minor_version = minorVersion; 184126a8a12Smrg smcConn->vendor = vendor; 185126a8a12Smrg smcConn->release = release; 186126a8a12Smrg smcConn->client_id = NULL; 187126a8a12Smrg 188126a8a12Smrg bzero ((char *) &smcConn->callbacks, sizeof (SmcCallbacks)); 189126a8a12Smrg set_callbacks (smcConn, mask, callbacks); 190126a8a12Smrg 191126a8a12Smrg smcConn->interact_waits = NULL; 192126a8a12Smrg smcConn->phase2_wait = NULL; 193126a8a12Smrg smcConn->prop_reply_waits = NULL; 194126a8a12Smrg 195126a8a12Smrg smcConn->save_yourself_in_progress = False; 196126a8a12Smrg smcConn->shutdown_in_progress = False; 197126a8a12Smrg 198126a8a12Smrg 199126a8a12Smrg /* 200126a8a12Smrg * Now register the client 201126a8a12Smrg */ 202126a8a12Smrg 203d656433aSmrg if (!previousId) 204d656433aSmrg previousId = ""; 205d656433aSmrg len = strlen (previousId); 206126a8a12Smrg extra = ARRAY8_BYTES (len); 207126a8a12Smrg 208126a8a12Smrg IceGetHeaderExtra (iceConn, _SmcOpcode, SM_RegisterClient, 209126a8a12Smrg SIZEOF (smRegisterClientMsg), WORD64COUNT (extra), 210126a8a12Smrg smRegisterClientMsg, pMsg, pData); 211126a8a12Smrg 212126a8a12Smrg STORE_ARRAY8 (pData, len, previousId); 213126a8a12Smrg 214126a8a12Smrg IceFlush (iceConn); 215126a8a12Smrg 216126a8a12Smrg replyWait.sequence_of_request = IceLastSentSequenceNumber (iceConn); 217126a8a12Smrg replyWait.major_opcode_of_request = _SmcOpcode; 218126a8a12Smrg replyWait.minor_opcode_of_request = SM_RegisterClient; 219126a8a12Smrg replyWait.reply = (IcePointer) &reply; 220126a8a12Smrg 221126a8a12Smrg gotReply = False; 222126a8a12Smrg ioErrorOccured = False; 223126a8a12Smrg 224126a8a12Smrg while (!gotReply && !ioErrorOccured) 225126a8a12Smrg { 226126a8a12Smrg ioErrorOccured = (IceProcessMessages ( 227126a8a12Smrg iceConn, &replyWait, &gotReply) == IceProcessMessagesIOError); 228126a8a12Smrg 229126a8a12Smrg if (ioErrorOccured) 230126a8a12Smrg { 231126a8a12Smrg if (errorStringRet && errorLength > 0) { 232126a8a12Smrg strncpy (errorStringRet, "IO error occured opening connection", 233126a8a12Smrg errorLength); 234126a8a12Smrg errorStringRet[errorLength - 1] = '\0'; 235126a8a12Smrg } 236126a8a12Smrg free (smcConn->vendor); 237126a8a12Smrg free (smcConn->release); 2383c15da26Smrg free (smcConn); 239126a8a12Smrg 240126a8a12Smrg return (NULL); 241126a8a12Smrg } 242126a8a12Smrg else if (gotReply) 243126a8a12Smrg { 244126a8a12Smrg if (reply.status == 1) 245126a8a12Smrg { 246126a8a12Smrg /* 247126a8a12Smrg * The client successfully registered. 248126a8a12Smrg */ 249126a8a12Smrg 250126a8a12Smrg *clientIdRet = reply.client_id; 251126a8a12Smrg 2523c15da26Smrg smcConn->client_id = strdup (*clientIdRet); 253126a8a12Smrg } 254126a8a12Smrg else 255126a8a12Smrg { 256126a8a12Smrg /* 257126a8a12Smrg * Could not register the client because the previous ID 258126a8a12Smrg * was bad. So now we register the client with the 259126a8a12Smrg * previous ID set to NULL. 260126a8a12Smrg */ 261126a8a12Smrg 262126a8a12Smrg extra = ARRAY8_BYTES (0); 263126a8a12Smrg 264126a8a12Smrg IceGetHeaderExtra (iceConn, _SmcOpcode, SM_RegisterClient, 265126a8a12Smrg SIZEOF (smRegisterClientMsg), WORD64COUNT (extra), 266126a8a12Smrg smRegisterClientMsg, pMsg, pData); 267126a8a12Smrg 268d656433aSmrg STORE_ARRAY8 (pData, 0, ""); 269126a8a12Smrg 270126a8a12Smrg IceFlush (iceConn); 271126a8a12Smrg 272126a8a12Smrg replyWait.sequence_of_request = 273126a8a12Smrg IceLastSentSequenceNumber (iceConn); 274126a8a12Smrg 275126a8a12Smrg gotReply = False; 276126a8a12Smrg } 277126a8a12Smrg } 278126a8a12Smrg } 279126a8a12Smrg 280126a8a12Smrg return (smcConn); 281126a8a12Smrg} 282126a8a12Smrg 283126a8a12Smrg 284126a8a12Smrg 285126a8a12SmrgSmcCloseStatus 286d656433aSmrgSmcCloseConnection(SmcConn smcConn, int count, char **reasonMsgs) 287126a8a12Smrg{ 288126a8a12Smrg IceConn iceConn = smcConn->iceConn; 289126a8a12Smrg smCloseConnectionMsg *pMsg; 290126a8a12Smrg char *pData; 291126a8a12Smrg int extra, i; 292126a8a12Smrg IceCloseStatus closeStatus; 293126a8a12Smrg SmcCloseStatus statusRet; 294126a8a12Smrg 295126a8a12Smrg extra = 8; 296126a8a12Smrg 297126a8a12Smrg for (i = 0; i < count; i++) 298126a8a12Smrg extra += ARRAY8_BYTES (strlen (reasonMsgs[i])); 299126a8a12Smrg 300126a8a12Smrg IceGetHeaderExtra (iceConn, _SmcOpcode, SM_CloseConnection, 301126a8a12Smrg SIZEOF (smCloseConnectionMsg), WORD64COUNT (extra), 302126a8a12Smrg smCloseConnectionMsg, pMsg, pData); 303126a8a12Smrg 304126a8a12Smrg STORE_CARD32 (pData, count); 305126a8a12Smrg pData += 4; 306126a8a12Smrg 307126a8a12Smrg for (i = 0; i < count; i++) 3083c15da26Smrg STORE_ARRAY8 (pData, strlen (reasonMsgs[i]), reasonMsgs[i]); 309126a8a12Smrg 310126a8a12Smrg IceFlush (iceConn); 311126a8a12Smrg 312126a8a12Smrg IceProtocolShutdown (iceConn, _SmcOpcode); 313126a8a12Smrg IceSetShutdownNegotiation (iceConn, False); 314126a8a12Smrg closeStatus = IceCloseConnection (iceConn); 315126a8a12Smrg 316126a8a12Smrg if (smcConn->vendor) 317126a8a12Smrg free (smcConn->vendor); 318126a8a12Smrg 319126a8a12Smrg if (smcConn->release) 320126a8a12Smrg free (smcConn->release); 321126a8a12Smrg 322126a8a12Smrg if (smcConn->client_id) 323126a8a12Smrg free (smcConn->client_id); 324126a8a12Smrg 325126a8a12Smrg if (smcConn->prop_reply_waits) 326126a8a12Smrg { 327126a8a12Smrg _SmcPropReplyWait *ptr = smcConn->prop_reply_waits; 328126a8a12Smrg _SmcPropReplyWait *next; 329126a8a12Smrg 330126a8a12Smrg while (ptr) 331126a8a12Smrg { 332126a8a12Smrg next = ptr->next; 3333c15da26Smrg free (ptr); 334126a8a12Smrg ptr = next; 335126a8a12Smrg } 3363c15da26Smrg 337126a8a12Smrg } 338126a8a12Smrg 3393c15da26Smrg free (smcConn); 340126a8a12Smrg 341126a8a12Smrg if (closeStatus == IceClosedNow) 342126a8a12Smrg statusRet = SmcClosedNow; 343126a8a12Smrg else if (closeStatus == IceClosedASAP) 344126a8a12Smrg statusRet = SmcClosedASAP; 345126a8a12Smrg else 346126a8a12Smrg statusRet = SmcConnectionInUse; 347126a8a12Smrg 348126a8a12Smrg return (statusRet); 349126a8a12Smrg} 350126a8a12Smrg 351126a8a12Smrg 352126a8a12Smrg 353126a8a12Smrgvoid 354d656433aSmrgSmcModifyCallbacks(SmcConn smcConn, unsigned long mask, SmcCallbacks *callbacks) 355126a8a12Smrg{ 356126a8a12Smrg set_callbacks (smcConn, mask, callbacks); 357126a8a12Smrg} 358126a8a12Smrg 359126a8a12Smrg 360126a8a12Smrg 361126a8a12Smrgvoid 362d656433aSmrgSmcSetProperties(SmcConn smcConn, int numProps, SmProp **props) 363126a8a12Smrg{ 364126a8a12Smrg IceConn iceConn = smcConn->iceConn; 365126a8a12Smrg smSetPropertiesMsg *pMsg; 366126a8a12Smrg char *pBuf; 367126a8a12Smrg char *pStart; 368126a8a12Smrg int bytes; 369126a8a12Smrg 370126a8a12Smrg IceGetHeader (iceConn, _SmcOpcode, SM_SetProperties, 371126a8a12Smrg SIZEOF (smSetPropertiesMsg), smSetPropertiesMsg, pMsg); 372126a8a12Smrg 373126a8a12Smrg LISTOF_PROP_BYTES (numProps, props, bytes); 374126a8a12Smrg pMsg->length += WORD64COUNT (bytes); 375126a8a12Smrg 376126a8a12Smrg pBuf = pStart = IceAllocScratch (iceConn, bytes); 377d656433aSmrg memset(pStart, 0, bytes); 378126a8a12Smrg 379126a8a12Smrg STORE_LISTOF_PROPERTY (pBuf, numProps, props); 380126a8a12Smrg 381126a8a12Smrg IceWriteData (iceConn, bytes, pStart); 382126a8a12Smrg IceFlush (iceConn); 383126a8a12Smrg} 384126a8a12Smrg 385126a8a12Smrg 386126a8a12Smrg 387126a8a12Smrgvoid 388d656433aSmrgSmcDeleteProperties(SmcConn smcConn, int numProps, char **propNames) 389126a8a12Smrg{ 390126a8a12Smrg IceConn iceConn = smcConn->iceConn; 391126a8a12Smrg smDeletePropertiesMsg *pMsg; 392126a8a12Smrg char *pData; 393126a8a12Smrg int extra, i; 394126a8a12Smrg 395126a8a12Smrg extra = 8; 396126a8a12Smrg 397126a8a12Smrg for (i = 0; i < numProps; i++) 398126a8a12Smrg extra += ARRAY8_BYTES (strlen (propNames[i])); 399126a8a12Smrg 400126a8a12Smrg IceGetHeaderExtra (iceConn, _SmcOpcode, SM_DeleteProperties, 401126a8a12Smrg SIZEOF (smDeletePropertiesMsg), WORD64COUNT (extra), 402126a8a12Smrg smDeletePropertiesMsg, pMsg, pData); 403126a8a12Smrg 404126a8a12Smrg STORE_CARD32 (pData, numProps); 405126a8a12Smrg pData += 4; 406126a8a12Smrg 407126a8a12Smrg for (i = 0; i < numProps; i++) 4083c15da26Smrg STORE_ARRAY8 (pData, strlen (propNames[i]), propNames[i]); 409126a8a12Smrg 410126a8a12Smrg IceFlush (iceConn); 411126a8a12Smrg} 412126a8a12Smrg 413126a8a12Smrg 414126a8a12Smrg 415126a8a12SmrgStatus 416d656433aSmrgSmcGetProperties(SmcConn smcConn, SmcPropReplyProc propReplyProc, 417d656433aSmrg SmPointer clientData) 418126a8a12Smrg{ 419126a8a12Smrg IceConn iceConn = smcConn->iceConn; 420126a8a12Smrg _SmcPropReplyWait *wait, *ptr; 421126a8a12Smrg 4223c15da26Smrg if ((wait = malloc (sizeof (_SmcPropReplyWait))) == NULL) 423126a8a12Smrg { 424126a8a12Smrg return (0); 425126a8a12Smrg } 426126a8a12Smrg 427126a8a12Smrg wait->prop_reply_proc = propReplyProc; 428126a8a12Smrg wait->client_data = clientData; 429126a8a12Smrg wait->next = NULL; 430126a8a12Smrg 431126a8a12Smrg ptr = smcConn->prop_reply_waits; 432126a8a12Smrg while (ptr && ptr->next) 433126a8a12Smrg ptr = ptr->next; 434126a8a12Smrg 435126a8a12Smrg if (ptr == NULL) 436126a8a12Smrg smcConn->prop_reply_waits = wait; 437126a8a12Smrg else 438126a8a12Smrg ptr->next = wait; 439126a8a12Smrg 440126a8a12Smrg IceSimpleMessage (iceConn, _SmcOpcode, SM_GetProperties); 441126a8a12Smrg IceFlush (iceConn); 442126a8a12Smrg 443126a8a12Smrg return (1); 444126a8a12Smrg} 445126a8a12Smrg 446126a8a12Smrg 447126a8a12Smrg 448126a8a12SmrgStatus 449d656433aSmrgSmcInteractRequest(SmcConn smcConn, int dialogType, 450d656433aSmrg SmcInteractProc interactProc, SmPointer clientData) 451126a8a12Smrg{ 452126a8a12Smrg IceConn iceConn = smcConn->iceConn; 453126a8a12Smrg smInteractRequestMsg *pMsg; 454126a8a12Smrg _SmcInteractWait *wait, *ptr; 455126a8a12Smrg 4563c15da26Smrg if ((wait = malloc (sizeof (_SmcInteractWait))) == NULL) 457126a8a12Smrg { 458126a8a12Smrg return (0); 459126a8a12Smrg } 460126a8a12Smrg 461126a8a12Smrg wait->interact_proc = interactProc; 462126a8a12Smrg wait->client_data = clientData; 463126a8a12Smrg wait->next = NULL; 464126a8a12Smrg 465126a8a12Smrg ptr = smcConn->interact_waits; 466126a8a12Smrg while (ptr && ptr->next) 467126a8a12Smrg ptr = ptr->next; 468126a8a12Smrg 469126a8a12Smrg if (ptr == NULL) 470126a8a12Smrg smcConn->interact_waits = wait; 471126a8a12Smrg else 472126a8a12Smrg ptr->next = wait; 473126a8a12Smrg 474126a8a12Smrg IceGetHeader (iceConn, _SmcOpcode, SM_InteractRequest, 475126a8a12Smrg SIZEOF (smInteractRequestMsg), smInteractRequestMsg, pMsg); 476126a8a12Smrg 477126a8a12Smrg pMsg->dialogType = dialogType; 478126a8a12Smrg 479126a8a12Smrg IceFlush (iceConn); 480126a8a12Smrg 481126a8a12Smrg return (1); 482126a8a12Smrg} 483126a8a12Smrg 484126a8a12Smrg 485126a8a12Smrg 486126a8a12Smrgvoid 487d656433aSmrgSmcInteractDone(SmcConn smcConn, Bool cancelShutdown) 488126a8a12Smrg{ 489126a8a12Smrg IceConn iceConn = smcConn->iceConn; 490126a8a12Smrg smInteractDoneMsg *pMsg; 491126a8a12Smrg 492126a8a12Smrg IceGetHeader (iceConn, _SmcOpcode, SM_InteractDone, 493126a8a12Smrg SIZEOF (smInteractDoneMsg), smInteractDoneMsg, pMsg); 494126a8a12Smrg 495126a8a12Smrg pMsg->cancelShutdown = cancelShutdown; 496126a8a12Smrg 497126a8a12Smrg IceFlush (iceConn); 498126a8a12Smrg} 499126a8a12Smrg 500126a8a12Smrg 501126a8a12Smrg 502126a8a12Smrgvoid 503d656433aSmrgSmcRequestSaveYourself(SmcConn smcConn, int saveType, Bool shutdown, 504d656433aSmrg int interactStyle, Bool fast, Bool global) 505126a8a12Smrg{ 506126a8a12Smrg IceConn iceConn = smcConn->iceConn; 507126a8a12Smrg smSaveYourselfRequestMsg *pMsg; 508126a8a12Smrg 509126a8a12Smrg IceGetHeader (iceConn, _SmcOpcode, SM_SaveYourselfRequest, 510126a8a12Smrg SIZEOF (smSaveYourselfRequestMsg), smSaveYourselfRequestMsg, pMsg); 511126a8a12Smrg 512126a8a12Smrg pMsg->saveType = saveType; 513126a8a12Smrg pMsg->shutdown = shutdown; 514126a8a12Smrg pMsg->interactStyle = interactStyle; 515126a8a12Smrg pMsg->fast = fast; 516126a8a12Smrg pMsg->global = global; 517126a8a12Smrg 518126a8a12Smrg IceFlush (iceConn); 519126a8a12Smrg} 520126a8a12Smrg 521126a8a12Smrg 522126a8a12Smrg 523126a8a12SmrgStatus 524d656433aSmrgSmcRequestSaveYourselfPhase2(SmcConn smcConn, 525d656433aSmrg SmcSaveYourselfPhase2Proc saveYourselfPhase2Proc, 526d656433aSmrg SmPointer clientData) 527126a8a12Smrg{ 528126a8a12Smrg IceConn iceConn = smcConn->iceConn; 529126a8a12Smrg _SmcPhase2Wait *wait; 530126a8a12Smrg 531126a8a12Smrg if (smcConn->phase2_wait) 532126a8a12Smrg wait = smcConn->phase2_wait; 533126a8a12Smrg else 534126a8a12Smrg { 5353c15da26Smrg if ((wait = malloc (sizeof (_SmcPhase2Wait))) == NULL) 536126a8a12Smrg { 537126a8a12Smrg return (0); 538126a8a12Smrg } 539126a8a12Smrg } 540126a8a12Smrg 541126a8a12Smrg wait->phase2_proc = saveYourselfPhase2Proc; 542126a8a12Smrg wait->client_data = clientData; 543126a8a12Smrg 544126a8a12Smrg smcConn->phase2_wait = wait; 545126a8a12Smrg 546126a8a12Smrg IceSimpleMessage (iceConn, _SmcOpcode, SM_SaveYourselfPhase2Request); 547126a8a12Smrg IceFlush (iceConn); 548126a8a12Smrg 549126a8a12Smrg return (1); 550126a8a12Smrg} 551126a8a12Smrg 552126a8a12Smrg 553126a8a12Smrg 554126a8a12Smrgvoid 555d656433aSmrgSmcSaveYourselfDone(SmcConn smcConn, Bool success) 556126a8a12Smrg{ 557126a8a12Smrg IceConn iceConn = smcConn->iceConn; 558126a8a12Smrg smSaveYourselfDoneMsg *pMsg; 559126a8a12Smrg 560126a8a12Smrg IceGetHeader (iceConn, _SmcOpcode, SM_SaveYourselfDone, 561126a8a12Smrg SIZEOF (smSaveYourselfDoneMsg), smSaveYourselfDoneMsg, pMsg); 562126a8a12Smrg 563126a8a12Smrg pMsg->success = success; 564126a8a12Smrg 565126a8a12Smrg IceFlush (iceConn); 566126a8a12Smrg} 567126a8a12Smrg 568126a8a12Smrg 569126a8a12Smrg 570126a8a12Smrgstatic void 571d656433aSmrgset_callbacks(SmcConn smcConn, unsigned long mask, SmcCallbacks *callbacks) 572126a8a12Smrg{ 573126a8a12Smrg if (mask & SmcSaveYourselfProcMask) 574126a8a12Smrg { 575126a8a12Smrg smcConn->callbacks.save_yourself.callback = 576126a8a12Smrg callbacks->save_yourself.callback; 577126a8a12Smrg smcConn->callbacks.save_yourself.client_data = 578126a8a12Smrg callbacks->save_yourself.client_data; 579126a8a12Smrg } 580126a8a12Smrg 581126a8a12Smrg if (mask & SmcDieProcMask) 582126a8a12Smrg { 583126a8a12Smrg smcConn->callbacks.die.callback = callbacks->die.callback; 584126a8a12Smrg smcConn->callbacks.die.client_data = callbacks->die.client_data; 585126a8a12Smrg } 586126a8a12Smrg 587126a8a12Smrg if (mask & SmcSaveCompleteProcMask) 588126a8a12Smrg { 589126a8a12Smrg smcConn->callbacks.save_complete.callback = 590126a8a12Smrg callbacks->save_complete.callback; 591126a8a12Smrg smcConn->callbacks.save_complete.client_data = 592126a8a12Smrg callbacks->save_complete.client_data; 593126a8a12Smrg } 594126a8a12Smrg 595126a8a12Smrg if (mask & SmcShutdownCancelledProcMask) 596126a8a12Smrg { 597126a8a12Smrg smcConn->callbacks.shutdown_cancelled.callback = 598126a8a12Smrg callbacks->shutdown_cancelled.callback; 599126a8a12Smrg smcConn->callbacks.shutdown_cancelled.client_data = 600126a8a12Smrg callbacks->shutdown_cancelled.client_data; 601126a8a12Smrg } 602126a8a12Smrg} 603