/* * XextAddDisplay - add a display to this extension */ XExtDisplayInfo *XextAddDisplay ( XExtensionInfo *extinfo, Display *dpy, _Xconst char *ext_name, XExtensionHooks *hooks, int nevents, XPointer data) { XExtDisplayInfo *dpyinfo; dpyinfo = (XExtDisplayInfo *) Xmalloc (sizeof (XExtDisplayInfo)); if (!dpyinfo) return NULL; dpyinfo->display = dpy; dpyinfo->data = data; dpyinfo->codes = XInitExtension (dpy, ext_name); /* * if the server has the extension, then we can initialize the * appropriate function vectors */ if (dpyinfo->codes) { int i, j; for (i = 0, j = dpyinfo->codes->first_event; i < nevents; i++, j++) { XESetWireToEvent (dpy, j, hooks->wire_to_event); XESetEventToWire (dpy, j, hooks->event_to_wire); } /* register extension for XGE */ if (strcmp(ext_name, GE_NAME)) xgeExtRegister(dpy, dpyinfo->codes->major_opcode, hooks); if (hooks->create_gc) XESetCreateGC (dpy, dpyinfo->codes->extension, hooks->create_gc); if (hooks->copy_gc) XESetCopyGC (dpy, dpyinfo->codes->extension, hooks->copy_gc); if (hooks->flush_gc) XESetFlushGC (dpy, dpyinfo->codes->extension, hooks->flush_gc); if (hooks->free_gc) XESetFreeGC (dpy, dpyinfo->codes->extension, hooks->free_gc); if (hooks->create_font) XESetCreateFont (dpy, dpyinfo->codes->extension, hooks->create_font); if (hooks->free_font) XESetFreeFont (dpy, dpyinfo->codes->extension, hooks->free_font); if (hooks->close_display) XESetCloseDisplay (dpy, dpyinfo->codes->extension, hooks->close_display); if (hooks->error) XESetError (dpy, dpyinfo->codes->extension, hooks->error); if (hooks->error_string) XESetErrorString (dpy, dpyinfo->codes->extension, hooks->error_string); } else if (hooks->close_display) { /* The server doesn't have this extension. * Use a private Xlib-internal extension to hang the close_display * hook on so that the "cache" (extinfo->cur) is properly cleaned. * (XBUG 7955) */ XExtCodes *codes = XAddExtension(dpy); if (!codes) { XFree(dpyinfo); return NULL; } XESetCloseDisplay (dpy, codes->extension, hooks->close_display); } /* * now, chain it onto the list */ _XLockMutex(_Xglobal_lock); dpyinfo->next = extinfo->head; extinfo->head = dpyinfo; extinfo->cur = dpyinfo; extinfo->ndisplays++; _XUnlockMutex(_Xglobal_lock); return dpyinfo; }
int CSDPSInit( Display *dpy, int *numberType, /* RETURN */ char **floatingName) /* RETURN */ { register Display *agent; register xCAPConnReplyPrefix *p; register char *c; DPSCAPData my; xCAPConnSetupReq setup; union { xCAPConnSuccess good; xCAPConnFailed bad; } reply; XExtData *extData; XExtCodes *codes; int indian; int rest; Window clientWindow; char fullDisplayName[MAXHOSTNAMELEN+10]; if (gCSDPS == NULL) DPSCAPStartUp(); /* To fix dps-nx #68, Motif too slow on HP */ if ((c = getenv("DPSNXGCMODE")) != 0) { gNXSyncGCMode = atoi(c); if (gNXSyncGCMode < DPSNXSYNCGCMODE_FLUSH || gNXSyncGCMode > DPSNXSYNCGCMODE_DELAYED) gNXSyncGCMode = DPSNXSYNCGCMODE_DEFAULT; } /* We may have already called this routine via XDPSExtensionPresent, so don't do it again! */ if ((codes = XDPSLGetCodes(dpy)) && (agent = XDPSLGetShunt(dpy)) && agent != dpy && codes->major_opcode == DPSXOPCODEBASE) return(DPSCAPSUCCESS); /* Try to create a window for ClientMessage communication */ clientWindow = XCreateSimpleWindow( dpy, DefaultRootWindow(dpy), 0, 0, 1, 1, 0, BlackPixel(dpy, DefaultScreen(dpy)), WhitePixel(dpy, DefaultScreen(dpy))); if (clientWindow == None) return(DPSCAPFAILED); /* Try to open a connection to an agent */ if ((extData = DPSCAPOpenAgent(dpy, fullDisplayName)) == NULL) { XDestroyWindow(dpy, clientWindow); return(DPSCAPFAILED); } /* DPSCAPOpenAgent only partially fills in extData, so finish it */ codes = XAddExtension(dpy); codes->major_opcode = DPSXOPCODEBASE; codes->first_event = 0; /* REQUIRED */ codes->first_error = FirstExtensionError; extData->number = codes->extension; extData->free_private = DPSCAPDestroy; my = (DPSCAPData) extData->private_data; my->codes = codes; agent = my->agent; /* +++ Is this all we have to do here? */ /* Send opening handshake */ indian = 1; if (*(char *) &indian) setup.byteorder = 'l'; else setup.byteorder = 'B'; setup.dpscapVersion = DPSCAPPROTOVERSION; setup.flags = DPSCAPNONEFLAG; setup.libraryversion = DPSPROTOCOLVERSION; setup.authProtoNameLength = 0; setup.authProtoDataLength = 0; setup.displayStringLength = strlen(fullDisplayName); setup.nodeStringLength = 0; setup.transportStringLength = 0; setup.display = 0; setup.screen = 0; setup.reserved = 0; setup.clientWindow = clientWindow; #ifndef DPSLNKL DPSCAPWrite(agent, (char *)&setup, sizeof(xCAPConnSetupReq), dpscap_nopad,dpscap_insert); DPSCAPWrite(agent, fullDisplayName, setup.displayStringLength, dpscap_pad, dpscap_append); N_XFlush(agent); #else /* DPSLNKL */ if (CSDPSConfirmDisplay(agent, dpy, &setup, &reply, fullDisplayName) == 1) { p = (xCAPConnReplyPrefix *)&reply.good; goto skip_read; } /* Read normal reply */ #endif /* DPSLNKL */ /* Read common reply prefix */ p = (xCAPConnReplyPrefix *)&reply.good; N_XRead(agent, (char *)p, (long)sizeof(xCAPConnReplyPrefix)); #ifdef DPSLNKL skip_read: #endif if (!p->success) { char mbuf[512]; /* read the rest */ c = (char *)&reply.bad.serverVersion; N_XRead(agent, c, sz_xCAPConnFailed - sz_xCAPConnReplyPrefix); sprintf(mbuf, "DPS NX: connection to \"%s\" refused by agent.", DisplayString(agent)); DPSWarnProc(NULL, mbuf); c = (char *)Xmalloc(reply.bad.reasonLength); if (!c) return(DPSCAPFAILED); N_XReadPad(agent, c, (long)reply.bad.reasonLength); if (!reply.bad.reasonLength) sprintf(mbuf, "DPS NX: (no reason given)\n"); else { strcpy(mbuf, "DPS NX: "); strncat(mbuf, c, reply.bad.reasonLength); mbuf[reply.bad.reasonLength+7] = '\0'; } DPSWarnProc(NULL, mbuf); Xfree(c); DPSCAPDestroy(extData); Xfree(extData); XDestroyWindow(dpy, clientWindow); return(DPSCAPFAILED); } /* read the rest of the fixed length reply */ c = (char *)&reply.good.serverVersion; rest = sizeof(xCAPConnSuccess) - sizeof(xCAPConnReplyPrefix); N_XRead(agent, c, rest); /* verify */ if (reply.good.serverVersion < DPSPROTOCOLVERSION) { /* Fine, we downgrade the client */ char qbuf[256]; sprintf(qbuf, "NX: server version %ld older than expected %d, client will downgrade", (long)reply.good.serverVersion, DPSPROTOCOLVERSION); DPSWarnProc(NULL, qbuf); } my->dpscapVersion = reply.good.dpscapVersion; if (my->dpscapVersion < DPSCAPPROTOVERSION) { /* Fine, we downgrade the client */ char kbuf[256]; sprintf(kbuf, "NX: agent version %d older than expected %d, client will downgrade", my->dpscapVersion, DPSCAPPROTOVERSION); DPSWarnProc(NULL, kbuf); #ifdef XXX /* Saving this code as a reminder about what needs to be cleaned up if we exit here */ DPSCAPDestroy(extData); Xfree(extData); XDestroyWindow(clientWindow); return(DPSCAPFAILED); #endif } if (numberType) *numberType = reply.good.preferredNumberFormat; /* read additional data */ c = (char *)Xmalloc(reply.good.floatingNameLength + 1); N_XReadPad(agent, c, reply.good.floatingNameLength); c[reply.good.floatingNameLength] = 0; if (floatingName) *floatingName = c; else Xfree(c); /* set library extension data */ XDPSLSetVersion(agent, reply.good.serverVersion); XDPSLSetVersion(dpy, reply.good.serverVersion); XDPSLSetShunt(dpy, agent); XDPSLSetCodes(dpy, codes); if (XDPSLGetSyncMask(dpy) == DPSCAP_SYNCMASK_NONE) XDPSLSetSyncMask(dpy, DPSCAP_SYNCMASK_DFLT); my->agentWindow = reply.good.agentWindow; XDPSLSetGCFlushMode(dpy, XDPSNX_GC_UPDATES_SLOW); /* default */ /* Hook my extension data on the dpy */ my->extData = extData; XAddToExtensionList(CSDPSHeadOfDpyExt(dpy), extData); (void) XESetCloseDisplay(dpy, codes->extension, DPSCAPCloseDisplayProc); (void) XESetCopyGC(dpy, codes->extension, DPSCAPCopyGCProc); (void) XESetFreeGC(dpy, codes->extension, DPSCAPFreeGCProc); (void) XESetFlushGC(dpy, codes->extension, DPSCAPFlushGCProc); XDPSLSetClientMessageHandler(dpy); /* Chain my data on global list */ my->next = gCSDPS->head; gCSDPS->head = my; #ifdef MAHALO /* Set function that is called after every Xlib protocol proc */ XDPSLSetAfterProc(dpy); /* All CSDPS protocol is auto-flushed */ (void) XSetAfterFunction(agent, DPSCAPFlushAfterProc); #endif /* MAHALO */ /* set agent arguments, if needed */ /* must follow setting of ShuntMap at least, so safest to do here when everything has been setup */ XDPSLUpdateAgentArgs(dpy); return(DPSCAPSUCCESS); }