/* * Send a reply string (notification) to client with id "name". * Return -1 if the window is invalid. */ int serverSendReply(VimRemotingClient *client, char *name, char *str) { char *property; int length; int res = 0; Window win = serverStrToWin(client, name); if (!isWindowValid(client, win)) return -1; #ifdef FEAT_MBYTE length = strlen(p_enc) + strlen(str) + 14; #else length = strlen(str) + 10; #endif if (!(property = malloc((unsigned)length + 30))) { return -1; } #ifdef FEAT_MBYTE sprintf(property, "%cn%c-E %s%c-n %s%c-w %x", 0, 0, p_enc, 0, str, 0, (unsigned int)client->window); #else sprintf(property, "%cn%c-n %s%c-w %x", 0, 0, str, 0, (unsigned int)client->window); #endif /* Add length of what "%x" resulted in. */ length += strlen(property + length); res = appendPropCarefully(client, win, client->commProperty, property, length + 1); free(property); return res; }
/* * Enter a loop processing X events & polling chars until we see a result */ static void serverWait(VimRemotingClient *client, Window w, VimRemotingClient_EndCond endCond, void *endData, int seconds) { time_t start; time_t now; time_t lastChk = 0; XEvent event; XPropertyEvent *e = (XPropertyEvent *)&event; int fd = ConnectionNumber(client->dpy); time(&start); while (!endCond(endData)) { time(&now); /* Just look out for the answer without calling back into Vim */ pollFor(fd, ((start + seconds) - now) * 1000); if (!isWindowValid(client, w)) break; while (XEventsQueued(client->dpy, QueuedAfterReading) > 0) { XNextEvent(client->dpy, &event); if (event.type == PropertyNotify && e->window == client->window) { serverEventProc(client, &event); } } } }
/* * Check for replies from id (win). * Return TRUE and a non-malloc'ed string if there is. Else return FALSE. */ static int serverPeekReply(VimRemotingClient *client, Window win, char **str) { VimRemotingClient_ServerReply *p; if ((p = findReply(client, win, SROP_Find)) != NULL && p->strings.ga_len > 0) { if (str != NULL) *str = p->strings.ga_data; return 1; } if (!isWindowValid(client, win)) return -1; return 0; }
void ChooseWindowPushButton::foundWindow(const WindowHandle &handle) { if(!isWindowValid(handle)) return; if(mLastFoundWindow) refreshWindow(mLastFoundWindow); highlightWindow(handle); mLastFoundWindow = handle; emit foundValidWindow(handle); }
bool ChooseWindowPushButton::x11EventFilter(XEvent *event) { if(event->type == ButtonRelease) { Window window = windowAtPointer(); if(window == None) return true; if(isWindowValid(window)) mLastFoundWindow = window; stopMouseCapture(); return true; } return false; }
/* * Fetch a list of all the Vim instance names currently registered for the * display. * * Returns a newline separated list in allocated memory or NULL. */ char *serverGetVimNames(VimRemotingClient *client) { unsigned char *regProp; char *entry; char *p; unsigned long numItems; unsigned int w; garray_T ga; ga_init2(&ga, 1, 100); /* * Read the registry property. */ if (getRegProp(client, ®Prop, &numItems)) return NULL; /* * Scan all of the names out of the property. */ ga_init2(&ga, 1, 100); for (p = (char *)regProp; (p - (char *)regProp) < numItems; p++) { entry = p; while (*p != 0 && !isspace(*(unsigned char *)p)) p++; if (*p != 0) { w = None; sscanf((char *)entry, "%x", &w); if (isWindowValid(client, (Window)w)) { ga_concat(&ga, p + 1); ga_concat(&ga, (char *)"\n"); } while (*p != 0) p++; } } if ((char *)regProp != empty_prop) XFree(regProp); ga_append(&ga, '\0'); return ga.ga_data; }
/* * Send to an instance of Vim via the X display. * Returns 0 for OK, negative for an error. */ int serverSendToVim(VimRemotingClient *client, const char *name, const char *cmd, apr_size_t cmd_len, char **result) { Window w; char *property; int length; int res; int n; VimRemotingClient_PendingCommand pending; if (result != NULL) *result = NULL; prologue(client); /* * Bind the server name to a communication window. * * Find any survivor with a serialno attached to the name if the * original registrant of the wanted name is no longer present. * * Delete any lingering names from dead editors. */ do { w = lookupName(client, name); /* Check that the window is hot */ } while (w != None && !isWindowValid(client, w)); if (w == None) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, client->server_rec, "Failed to connect the server %s", name); epilogue(client); return -1; } /* * Send the command to target interpreter by appending it to the * comm window in the communication window. * Length must be computed exactly! */ #ifdef FEAT_MBYTE length = strlen(name) + strlen(p_enc) + cmd_len + 14; #else length = strlen(name) + cmd_len + 10; #endif property = (char *)malloc((unsigned)length + 30); #ifdef FEAT_MBYTE n = sprintf((char *)property, "%c%c%c-n %s%c-E %s%c-s ", 0, result ? 'c' : 'k', 0, name, 0, p_enc, 0); #else n = sprintf((char *)property, "%c%c%c-n %s%c-s ", 0, result ? 'c' : 'k', 0, name, 0); #endif { memcpy(property + n, cmd, cmd_len); property[n + cmd_len] = '\0'; } /* Add a back reference to our comm window */ client->serial++; sprintf((char *)property + length, "%c-r %x %d", 0, (unsigned int)client->window, client->serial); /* Add length of what "-r %x %d" resulted in, skipping the NUL. */ length += strlen(property + length + 1) + 1; res = appendPropCarefully(client, w, client->commProperty, property, length + 1); free(property); if (res < 0) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, client->server_rec, "Failed to send command to the destination program"); epilogue(client); return -1; } if (!result) { /* There is no answer for this - Keys are sent async */ epilogue(client); return client->got_x_error; } /* * Register the fact that we're waiting for a command to * complete (this is needed by SendEventProc and by * AppendErrorProc to pass back the command's results). */ pending.serial = client->serial; pending.code = 0; pending.result = NULL; pending.nextPtr = client->pendingCommands; client->pendingCommands = &pending; serverWait(client, w, waitForPend, &pending, 600); /* * Unregister the information about the pending command * and return the result. */ if (client->pendingCommands == &pending) { client->pendingCommands = pending.nextPtr; } else { VimRemotingClient_PendingCommand *pcPtr; for (pcPtr = client->pendingCommands; pcPtr; pcPtr = pcPtr->nextPtr) { if (pcPtr->nextPtr == &pending) { pcPtr->nextPtr = pending.nextPtr; break; } } } if (result) *result = pending.result; else free(pending.result); epilogue(client); return pending.code == 0 ? 0 : -1; }