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 + -
显示快捷键?