xsend.c
来自「speech signal process tools」· C语言 代码 · 共 1,229 行 · 第 1/3 页
C
1,229 行
intRead_X_Comm(display, window, xevent, raw, buffer, max_length, callback) Display *display; Window window; char *buffer; int max_length; XEvent *xevent; int raw; void (*callback) (); /* dest, calling_win, serial, req, * script */{ char *propInfo, *p; int result, actualFormat; unsigned long numItems, bytesAfter; Atom actualType; int line_count = 0; spsassert(display, "Read_X_Comm: display is NULL"); spsassert(window, "Read_X_Comm: window is NULL"); spsassert(xevent, "Read_X_Comm: xevent is NULL"); if ((xevent->xproperty.atom != commProperty) || (xevent->xproperty.state != PropertyNewValue)) { return 0; } propInfo = NULL; result = XGetWindowProperty(display, window, commProperty, 0, MAX_PROP_WORDS, True, XA_STRING, &actualType, &actualFormat, &numItems, &bytesAfter, (unsigned char **) &propInfo); /* * If the property doesn't exist or is improperly formed then ignore it. */ if ((result != Success) || (actualType != XA_STRING) || (actualFormat != 8)) { if (propInfo != NULL) { XFree(propInfo); } return 0; } if (!callback && raw) { if (numItems > max_length - 1) numItems = max_length - 1; memcpy(buffer, propInfo, numItems); buffer[numItems] = '\0'; XFree(propInfo); return 1; } else { /* * Several commands and results could arrive in the property at one * time; each iteration through the outer loop handles a single * command or result. */ for (p = propInfo; (p - propInfo) < numItems;) { /* * Ignore leading NULLs; each command or result starts with a NULL * so that no matter how badly formed a preceding command is, we'll * be able to tell that a new command/result is starting. */ if (*p == 0) { p++; continue; } if ((*p == 'c') && (p[1] == 0)) { char *dest, *script, *end; char *bptr = buffer; int req, l, serial; Window commWindow; /* * -------------------------------------------- -------------- * This is an incoming command from some other application. * Iterate over all of its options. Stop when we reach the end * of the property or something that doesn't look like an option. * ------------------------------------------- --------------- */ p += 2; script = NULL; req = IMMEDIATE_RESPONSE; commWindow = None; serial = 0; while (((p - propInfo) < numItems) && (*p == '-')) { switch (p[1]) { case 'R': /* old rpc request code */ if (p[2] == ' ') { req = atoi(p + 3); } break; case 'r': commWindow = (Window) (unsigned long) strtol(p + 2, &end, 16); if ((end == p + 2) || (*end != ' ')) { commWindow = None; } else { p = end + 1; serial = (unsigned long) atoi(p); } break; case 'n': if (p[2] == ' ') { dest = p + 3; } break; case 's': if (p[2] == ' ') { script = p + 3; } break; } while (*p != 0) { p++; } p++; } if (script == NULL) { continue; } if (*script == '-' && strcmp(script + 1, "reply")) { req = INTERLOCK_DELAY_RESPONSE_TK; script += 7; } if (callback) { if (debug_level) fprintf(stderr, "Comm Msg callback:\n%s %x %d %d\n%s\n", dest, commWindow, serial, req, script); callback(dest, commWindow, serial, req, script); } else { l = strlen(script); memcpy(bptr, script, l < max_length ? l : max_length); line_count++; bptr += l; if (bptr - buffer >= max_length) break; *bptr++ = '\0'; } } else { /* * Didn't recognize this thing. Just skip through the next null * character and try again. */ while (*p != 0) { p++; } p++; } } XFree(propInfo); return line_count; }}static char *Read_X_Reply(display, window, xevent, serial_expected) Display *display; Window window; XEvent *xevent; int serial_expected;{ char *propInfo, *p; int result, actualFormat; unsigned long numItems, bytesAfter; Atom actualType; spsassert(display, "Read_X_Comm: display is NULL"); spsassert(window, "Read_X_Comm: window is NULL"); spsassert(xevent, "Read_X_Comm: xevent is NULL"); if ((xevent->xproperty.atom != commProperty) || (xevent->xproperty.state != PropertyNewValue)) { return NULL; } propInfo = NULL; result = XGetWindowProperty(display, window, commProperty, 0, MAX_PROP_WORDS, True, XA_STRING, &actualType, &actualFormat, &numItems, &bytesAfter, (unsigned char **) &propInfo); /* * If the property doesn't exist or is improperly formed then ignore it. */ if ((result != Success) || (actualType != XA_STRING) || (actualFormat != 8)) { if (propInfo != NULL) { XFree(propInfo); } return NULL; } for (p = propInfo; (p - propInfo) < numItems;) { /* * Ignore leading NULLs; each command or result starts with a NULL so * that no matter how badly formed a preceding command is, we'll be * able to tell that a new command/result is starting. */ if (*p == 0) { p++; continue; } if ((*p == 'r') && (p[1] == 0)) { int serial, gotSerial; char *resultString, *result; p += 2; gotSerial = 0; resultString = NULL; while (((p - propInfo) < numItems) && (*p == '-')) { switch (p[1]) { case 'r': if (p[2] == ' ') { resultString = p + 3; } break; case 's': if (sscanf(p + 2, " %d", &serial) == 1) { gotSerial = 1; if (serial_expected == -1) serial_expected = serial; } break; } while (*p != 0) { p++; } p++; } if (!gotSerial || (serial != serial_expected)) { continue; } result = strdup(resultString); XFree(propInfo); return result; } else { while (*p != 0) { p++; } p++; } } XFree(propInfo); return NULL;}static voidUpdateCommWindow(display, window, name) Display *display; Window window; char *name;{ int (*defaultHandler) () = NULL; spsassert(display, "UpdateCommWindow: display is NULL"); spsassert(window, "UpdateCommWindow: window is NULL"); spsassert(name, "UpdateCommWindow: name is NULL"); defaultHandler = XSetErrorHandler(XSend_Update_Handler); XChangeProperty(display, window, appNameProperty, XA_STRING, 8, PropModeReplace, name, strlen(name) + 1); XSync(display, FALSE); (void) XSetErrorHandler(defaultHandler);}static NameRegistry *RegOpen(display, lock) Display *display; int lock;{ NameRegistry *regPtr; int result, actualFormat; unsigned long bytesAfter; Atom actualType; spsassert(display, "RegOpen: display is NULL"); regPtr = (NameRegistry *) malloc(sizeof(NameRegistry)); regPtr->display = display; regPtr->locked = 0; regPtr->modified = 0; regPtr->allocedByX = 1; if (lock && !debug_level) { XGrabServer(display); regPtr->locked = 1; } /* * Read the registry property */ result = XGetWindowProperty(display, RootWindow(display, 0), registryProperty, 0, MAX_PROP_WORDS, False, XA_STRING, &actualType, &actualFormat, ®Ptr->propLength, &bytesAfter, (unsigned char **) ®Ptr->property); if (actualType == None) { regPtr->propLength = 0; regPtr->property = NULL; } else if ((result != Success) || (actualFormat != 8) || (actualType != XA_STRING)) { /* * The property is improperly formed; delete it. */ if (regPtr->property != NULL) { XFree(regPtr->property); regPtr->propLength = 0; regPtr->property = NULL; } XDeleteProperty(display, RootWindow(display, 0), registryProperty); } /* * Xlib placed an extra null byte after the end of the property, just to * make sure that it is always NULL-terminated. Be sure to include this * byte in our count if it's needed to ensure null termination */ if ((regPtr->propLength > 0) && (regPtr->property[regPtr->propLength - 1] != 0)) { regPtr->propLength++; } if (debug_level) { fprintf(stderr, "RegOpen: Property:\n"); print_prop(regPtr); fprintf(stderr, "\n"); } return regPtr;}static WindowRegFindName(regPtr, name) NameRegistry *regPtr; /* Pointer to a registry opened with a * previous call to RegOpen. */ char *name; /* Name of an application. */{ char *p, *entry; Window commWindow; commWindow = None; for (p = regPtr->property; (p - regPtr->property) < regPtr->propLength;) { entry = p; while ((*p != 0) && (!isspace(UCHAR(*p)))) { p++; } if ((*p != 0) && (strcmp(name, p + 1) == 0)) { if (sscanf(entry, "%x", (unsigned int *) &commWindow) == 1) { return commWindow; } } while (*p != 0) { p++; } p++; } return None;}static intRegDeleteName(regPtr, name) NameRegistry *regPtr; /* Pointer to a registry opened with a * previous call to RegOpen. */ char *name; /* Name of an application. */{ char *p, *entry, *entryName; int count; for (p = regPtr->property; (p - regPtr->property) < regPtr->propLength;) { entry = p; while ((*p != 0) && (!isspace(UCHAR(*p)))) { p++; } if (*p != 0) { p++; } entryName = p; while (*p != 0) { p++; } p++; if ((strcmp(name, entryName) == 0)) { /* * Found the matching entry. Copy everything after it down on top * of it. */ count = regPtr->propLength - (p - regPtr->property); if (count > 0) { memmove((void *) entry, (void *) p, (size_t) count); } regPtr->propLength -= p - entry; regPtr->modified = 1; return 1; } } return 0;}static voidRegAddName(regPtr, name, commWindow) NameRegistry *regPtr; /* Pointer to a registry opened with a * previous call to RegOpen. */ char *name; /* Name of an application. The caller must * ensure that this name isn't already
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?