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,			       &regPtr->propLength, &bytesAfter,			       (unsigned char **) &regPtr->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 + -
显示快捷键?