xsend.c

来自「speech signal process tools」· C语言 代码 · 共 1,229 行 · 第 1/3 页

C
1,229
字号
/* * This material contains unpublished, proprietary software of Entropic * Research Laboratory, Inc. Any reproduction, distribution, or publication * of this work must be authorized in writing by Entropic Research * Laboratory, Inc., and must bear the notice: *  * "Copyright (c) 1995 Entropic Research Laboratory, Inc. All rights reserved" *  * The copyright notice above does not evidence any actual or intended * publication of this source code. *  * Written by:  Alan Parker Checked by: Revised by: *  * Brief description: Tk communications routines for non tcl/tk programs *  * This code is heavily derived from the tkSend.c file in the TK 4.0 source code * written by John Ousterhout. *  */static char    *sccs_id = "@(#)xsend.c	1.7	8/22/97	ERL";#ifndef DEC_ALPHA#define memmove memcpy#endif#include <stdio.h>#include <esps/spsassert.h>#include <esps/xwaves_ipc.h>#include <sys/time.h>#include <X11/Xlib.h>#include <X11/Intrinsic.h>#include <X11/Xatom.h>#define COMM_PROP 	"Comm"#define REGIS_PROP 	"InterpRegistry"#define APPNAME_PROP 	"TK_APPLICATION"#define MAX_PROP_WORDS 100000#define UCHAR(c) ((unsigned char) (c))extern int      debug_level;char	       *strdup();static int      SendSerial = 0;static Atom     commProperty = 0;static Atom     registryProperty = 0;static Atom     appNameProperty = 0;static Window   myWindow = None;static int      XSend_Error = 0;static char    *SendXwaves_defname = "default_xwaves_client";#define DEBUG 0typedef struct NameRegistry {   Display        *display;	/* Display from which registry was read */   int             locked;	/* Non-zero means the display was locked when				 * the property was read in */   int             modified;	/* Non-zero means that the property has been				 * modified, so it needs to be written out				 * when the NameRegistry is closed */   unsigned long   propLength;	/* Length of the property in bytes */   char           *property;	/* The contents of the property.  See format				 * above; this is not terminated by the first				 * null character. */   int             allocedByX;	/* Non-zero  means must free property with				 * XFree; zero means use free */}               NameRegistry;static void     RegAddName();static void     RegClose();static int      RegDeleteName();static Window   RegFindName();static NameRegistry *RegOpen();static int      ValidateName();static int      SplitList();static void     UpdateCommWindow();static void     AppendProp();static void     print_prop();static void     print_data();static int      XSend_Handler();static int      XSend_Update_Handler();static void     Usleep();Sxptr          *OpenXwaves();void            CloseXwaves();/* * This function is called by the client application to setup for X server * based communications.   The name passed in is typically the application * name, but it might be changed in order to be unique amoung registered * applications.   The application is registered by adding its name and XID * of a window to the InterpRegistry property of the display's root window. * Arguments: name	The name of the application to register under. * display The X display. window  The X window to use as a communications * window. *  * Return value: the function returns the actual name used in the registry.  It * might have been changed. */char           *Setup_X_Comm(name, display, window)   char           *name;   Display        *display;   Window          window;{   NameRegistry   *regPtr;   Window          w;   char           *actualName, *string;   int             i;   spsassert(name, "Setup_X_Comm name is NULL");   spsassert(display, "Setup_X_Comm display is NULL");   spsassert(window, "Setup_X_Comm w is NULL");   commProperty = XInternAtom(display, COMM_PROP, FALSE);   registryProperty = XInternAtom(display, REGIS_PROP, FALSE);   appNameProperty = XInternAtom(display, APPNAME_PROP, FALSE);   if (debug_level)      fprintf(stderr, "Setup_X_Comm: name: %s, display: %x, win: %x\n",	      name, display, window);   regPtr = RegOpen(display, 1);   actualName = name;   w = RegFindName(regPtr, actualName);   if (w != None) {		/* name may be already in use */      /*       * First, try to determine if the registered name is for real.  It       * could be that an application died and left its name registered.       */      if (debug_level)	 fprintf(stderr, "found a %s, checking..");      if (ValidateName(display, actualName, w)) {	/* Name is in use */	 if (debug_level)	    fprintf(stderr, "name is in use\n");	 string = (char *) malloc(strlen(actualName) + 15);	 for (i = 2;; i++) {	    sprintf(string, "%s_#%d", actualName, i);	    w = RegFindName(regPtr, string);	    if (w == None) {	       actualName = string;	       break;	    }	    if (!ValidateName(display, string, w)) {	       if (debug_level)		  fprintf(stderr, ", bad name, remove it\n");	       while (RegDeleteName(regPtr, string));;	       actualName = string;	       break;	    }	 }	 if (debug_level)	    fprintf(stderr, " new name is %s\n", actualName);      } else {	 if (debug_level)	    fprintf(stderr, "found stale name, remove it\n");	 while (RegDeleteName(regPtr, actualName));;      }   }   /*    * We now have a name to use.  Store it in the name registry.    */   RegAddName(regPtr, actualName, window);   RegClose(regPtr);   /*    * The following just updates the APPNAME_PROP with actualName. Note that    * Tk might have many apps per process, we have only one.    */   UpdateCommWindow(display, window, actualName);   myWindow = window;   return actualName;}WindowGet_X_Comm_Win(display, name)   Display        *display;   char           *name;{   NameRegistry   *regPtr;   Window          win;   spsassert(display && name, "Get_X_Comm_Win display or name NULL");   regPtr = RegOpen(display, 0);   win = RegFindName(regPtr, name);   RegClose(regPtr);   return win;}/* * Send a message.  The message sent is sent without the -r option, which * means that the message is async and no reply is required. Arguments: * display	The X display of the destination application. destname The * name of the destination application. msg	The message to send. length * The length of the message. *  * Return value: The return value is 1 for OK, 0 for Error (i.e. message not * sent) */intSend_X_Msg(display, destname, window, req, msg, length)   Display        *display;   char           *destname;   Window          window;   int             req;		/* like the RPC request code */   char           *msg;   int             length;{   char            *buffer;   NameRegistry   *regPtr;   int             len;   Window          win;#define SEND_CODE1 "\0c\0-n "#define SEND_CODE1_LEN 6#define SEND_CODE2 "\0-R "#define SEND_CODE2_LEN 4#define SEND_CODE3 "\0-r "#define SEND_CODE3_LEN 4#define SEND_CODE4 "\0-s "#define SEND_CODE4_LEN 4/* cannot use strlen on the above! */   XSend_Error = 0;   spsassert(destname || (window != None), "destname and win NULL");   if (!msg || length < 1)      return 0;   if (debug_level)      fprintf(stderr, "Send_X_Msg: msg: %s, len: %d\n", msg, length);   if (window == None) {      regPtr = RegOpen(display, 0);      win = RegFindName(regPtr, destname);      RegClose(regPtr);      if (win == None)	 return 0;   } else      win = window;   if (req > IMMEDIATE_RESPONSE || req < RPCINFO_CALL)      req = IMMEDIATE_RESPONSE;   SendSerial++;   buffer = (char *)malloc(length+SEND_CODE1_LEN+SEND_CODE2_LEN+                           SEND_CODE3_LEN+SEND_CODE4_LEN+strlen(destname)+100);   (void) memcpy(buffer, SEND_CODE1, SEND_CODE1_LEN);   len = SEND_CODE1_LEN;   (void) memcpy(buffer + len, destname, strlen(destname));   len += strlen(destname);   if (req != IMMEDIATE_RESPONSE) {      (void) memcpy(buffer + len, SEND_CODE2, SEND_CODE2_LEN);      len += SEND_CODE2_LEN;      sprintf(buffer + len, "%d", req);      len += strlen(buffer + len);      (void) memcpy(buffer + len, SEND_CODE3, SEND_CODE3_LEN);      len += SEND_CODE3_LEN;      sprintf(buffer + len, "%x %d", myWindow, SendSerial);      len += strlen(buffer + len);   }   (void) memcpy(buffer + len, SEND_CODE4, SEND_CODE4_LEN);   len += SEND_CODE4_LEN;   (void) memcpy(buffer + len, msg, length);   len += length;   buffer[len] = '\0';   if (debug_level) {      int             i;      fprintf(stderr, "Send_X_Msg: message length %d content:\n", len + 1);      for (i = 0; i < len + 1; i++)	 if (buffer[i] == '\0')	    fprintf(stderr, "<null>");	 else	    fputc(buffer[i], stderr);      fprintf(stderr, "\nEnd of message\n");   }   AppendProp(display, win, commProperty, buffer, len + 1);   free(buffer);   return (XSend_Error == 0);}intSend_X_Reply(display, destname, window, serial, msg, length)   Display        *display;   char           *destname;   Window          window;   int             serial;   char           *msg;   int             length;{   char            *buffer;   NameRegistry   *regPtr;   int             len;   Window          win;   char            str[100];#define REPLY_CODE1 "\0r\0-s "#define REPLY_CODE2 "\0-r "/* Cannot use strlen on these since they contain null!*/#define REPLY_CODE1_LEN 6#define REPLY_CODE2_LEN 4   XSend_Error = 0;   spsassert(destname || (window != None), "destname and win NULL");   if (!msg || length < 1)      return 0;   if (debug_level)      fprintf(stderr, "Send_X_Reply: msg: %s, len: %d\n", msg, length);   if (destname) {      regPtr = RegOpen(display, 0);      win = RegFindName(regPtr, destname);      RegClose(regPtr);      if (win == None)	 return 0;   } else      win = window;   sprintf(str, "%d", serial);   SendSerial++;   buffer = (char *)malloc(REPLY_CODE1_LEN+strlen(str)+			   REPLY_CODE2_LEN+length+1);   (void) memcpy(buffer, REPLY_CODE1, REPLY_CODE1_LEN);   len = 6;   (void) memcpy(buffer + len, str, strlen(str));   len += strlen(str);   (void) memcpy(buffer + len, REPLY_CODE2, REPLY_CODE2_LEN);   len += 4;   (void) memcpy(buffer + len, msg, length);   len += length;   buffer[len] = '\0';   if (debug_level) {      int             i;      fprintf(stderr, "Send_X_Reply: message length %d content:\n", len + 1);      for (i = 0; i < len + 1; i++)	 if (buffer[i] == '\0')	    fprintf(stderr, "<null>");	 else	    fputc(buffer[i], stderr);      fprintf(stderr, "\nEnd of message\n");   }   AppendProp(display, win, commProperty, buffer, len + 1);   free(buffer);   return (XSend_Error == 0);}/* * Unregister the application. *  * Arguments: display	The X display. name	The name of the application * to unregister. */voidClose_X_Comm(display, name)   Display        *display;   char           *name;{   NameRegistry   *regPtr;   Window          window;   spsassert(display, "Close_X_Comm: display is NULL");   spsassert(name, "Close_X_Comm: name is NULL");   regPtr = RegOpen(display, 1);   window = RegFindName(regPtr, name);   RegDeleteName(regPtr, name);   RegClose(regPtr);   if (window != None)      UpdateCommWindow(display, window, " ");}/* * Read the message from the designated communications window.  The * assumption is that the calling program has been notified of the * XPropertyChanged event.   The message can be returned in one of two * formats.  One is "raw", which means that the entire contents of the * property is returned, including Tk options.   The other format is non-raw, * and this means that just the "script" part (the command itself) is * returned.   Note that in either format it is possible that multiple * commands are returned.  They will be separated by NULLs. *  * Arguments: display	The X display. window  The X window to read from. * xevent  The X event structuure this event. raw	1 means return raw * data, 0 means return command only buffer	Pointer to space for the * return data. max_length The maximum number of bytes to copy to buffer. If * non raw mode, then a new command will not be added to buffer unless it * will all fit. *  * Return value: Number of commands read.  For raw mode, it returns 1; * regardless of the number of raw commands in the buffer.  For non raw, it * is the number of null separated commands in the buffer. If no data is * read, then zero is returned. */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?