📄 message.c
字号:
/* * 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-1996 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: Dave Talkin * Checked by: * Revised by: Alan Parker * * Brief description: provides IPC functions for waves and attachments * */static char *sccs_id = "@(#)message.c 1.19 1/18/97 ERL";#include <stdio.h>#ifdef LINUX#include <sys/ioctl.h>#else#include <sgtty.h>#endif#include <Methods.h>#include <w_lengths.h>#include <esps/xwaves_ipc.h>#include <xview/xview.h>#define TRUE 1#define FALSE 0char ok[] = "ok", null[] = "null";char *get_next_item(), *get_next_line(), *savestring();char *get_methods(), *make_new_object();static char *builtin_default_execute_proc();extern char *exec_waves();extern char notice_msg[];/* This gets called if a message receiver can not be found. */static char *(*default_proc) () = builtin_default_execute_proc;/* * This stores information about what to do after a waves command is * executed. The caller ID, some data and a procedure pointer are stored to * accomplish the callback. */typedef struct pending_calls { int id; void (*proc) (); void *data; struct pending_calls *next, *prev;} PendCalls;/* The master list of pending callbacks. */static PendCalls *pring = NULL;static int pending_call_id = 1;/* The master list of items on the incomingd ispatch queue. */static StrList *dq = NULL;/* Message buffers for incoming and outgoing IPC messages. */static char in[1000], out[1000], *pin = in, *pout = out;extern int w_verbose, debug_level;extern char *thisprog; /* points to exact invocation name for this * program. *//* these are all set in setup_ipc */Display *X_Display = NULL;Window comm_window = None;char *registry_name = NULL;char *remote_name = NULL;Window remote_comm_window = None;/*********************************************************************** get_receiver_name(), get_methods(), and get_receiver() must be defined to mesh the application specific structures to (char*). ***********************************************************************//***********************************************************************/char *(* install_default_execute_proc(newproc)) () char *(*newproc) ();{ char *(*hold) () = default_proc; default_proc = newproc; return (hold);}/***********************************************************************/static char *builtin_default_execute_proc(who, str) char *who, *str;{ char name[500]; strnscan(str, name, sizeof(name)); sprintf(notice_msg, "Unknown command name %s; command ignored", name); show_notice(1,notice_msg); return (null);}static void *command_step_caller = NULL;static char *command_step_resp = NULL;/*********************************************************************/voidprepare_to_resume_ipc(caller, data) void *caller; char *data;{ command_step_caller = caller; command_step_resp = data;}/***********************************************************************/resume_ipc_if_stepping(){ do_ipc_response_if_any(command_step_caller, command_step_resp); command_step_caller = NULL; command_step_resp = NULL;}/***********************************************************************/char *execute_command(wh, methods, str) register char *wh; register Methods *methods; register char *str;{ char name[100], str2[MES_BUF_SIZE]; register int n; register Methods *m2; extern int command_step;/* whether or not to single-step command * files */ extern int command_paused; /* whether or not to pause after * command */ if (debug_level) { if (str) fprintf(stderr, "execute_command: entered with str = \"%s\"\n", str); else fprintf(stderr, "execute_command: entered with str = NULL\n"); } if (str && *str) { if (!wh) { strcpy(str2, str); if ((wh = (char *) make_new_object(str))) { methods = (Methods *) get_methods(wh); str = get_next_item(str2); } if (debug_level) fprintf(stderr, "execute_command: str = %s\n", str); } if (w_verbose > 1) fprintf(stderr, "Executing command: %s\n", str); if (wh && str && *str) { strnscan(str, name, sizeof(name)); n = strlen(name); while (methods) { if (!strncmp(name, methods->name, n)) { /* found a match */ if (strlen(methods->name) != n) { /* an exact match? */ m2 = methods->next; /* check for uniqueness */ while (m2) { if (!strncmp(name, m2->name, n)) { sprintf(notice_msg, "Non-unique command name %s; command ignored", name); show_notice(1,notice_msg); return (null); /* found a dup. */ } m2 = m2->next; } } if (command_step) { void *in_a_ipc_dispatch(), *hand = in_a_ipc_dispatch(); char *resp; command_paused = 1; (void) fprintf(stderr, "command: %s", str); if (str[strlen(str) - 1] != '\n') (void) fprintf(stderr, "\n"); resp = methods->meth(wh, get_next_item(str)); prepare_to_resume_ipc(hand, resp); return (resp); } else return (methods->meth(wh, get_next_item(str))); } methods = methods->next; } /* fall-through to last-resort */ if (default_proc) return (default_proc(wh, str)); } } return (null);}/***********************************************************************/set_return_value_callback(proc, data) void (*proc) (); void *data;{ if (proc) { PendCalls *pc = (PendCalls *) malloc(sizeof(PendCalls)); if (pc) { if (pring) { pc->next = pring->next; pring->next->prev = pc; pring->next = pc; pc->prev = pring; } else { pring = pc; pc->next = pc; pc->prev = pc; } pc->proc = proc; pc->data = data; pc->id = pending_call_id; pending_call_id++; if (!pending_call_id) pending_call_id = 1; if (debug_level) fprintf(stderr, "Set callback id:%d %x %x\n", pc->id, proc, data); return (pc->id); } else fprintf(stderr, "Allocation failure in set_return_callback()\n"); } else fprintf(stderr, "NULL proc passed to set_return_callback()\n"); return (0);}/***********************************************************************/do_return_callback(id, str) int id; char *str;{ if (id) { PendCalls *pc0 = pring, *pc = pc0; void (*pr) (); void *dat; if (debug_level) fprintf(stderr, "Do callback id:%d;%s\n", id, (str) ? str : null); if (pring) { do { if (pc->id == id) { if (pc->next != pc) { pc->prev->next = pc->next; pc->next->prev = pc->prev; pring = pc->next; } else pring = NULL; dat = pc->data; pr = pc->proc; free(pc); if (debug_level) fprintf(stderr, "Entering callback id:%d %x %x\n", id, pr, dat); pr(dat, str); if (debug_level) fprintf(stderr, "Done with callback id:%d\n", id); return (TRUE); } pc = pc->next; } while (pc != pc0); } else { fprintf(stderr, "No more callback entries!\n"); fprintf(stderr, "Failed to find callback id:%d!\n", id); return (FALSE); } } else { fprintf(stderr, "Zero ID passed to do_return_callback()\n"); return (FALSE); }}/***********************************************************************/char *dispatch(str) char *str;{ char *wh, *get_receiver(), *get_receiver_name(), *get_methods(), cd, *cdp; if (debug_level) { if (str) fprintf(stderr, "dispatch: entered with str = \"%s\"\n", str); else fprintf(stderr, "dispatch: entered with str = NULL\n"); } if (!str) return null; if (str && (((cd = *str) == '"') || (cd == '\''))) { cdp = ++str; while (*cdp && (*cdp != cd)) cdp++; if (*cdp) *cdp = ' '; } if ((wh = get_receiver(str))) { if (!*(str = get_next_item(str))) { if (debug_level) fprintf(stderr, "null message to %s\n", get_receiver_name(wh)); return (null); } return (execute_command(wh, get_methods(wh), str)); } if (debug_level) fprintf(stderr, "%s was not found; will try to create it.\n", str); return (execute_command(NULL, get_methods(NULL), str));}#define ITIMER_NULL ((struct itimerval*)0)static int under_xview = 1;static void (*sigsave) () = NULL;/*************************************************************************/set_no_xview(){ under_xview = 0;}/*************************************************************************/restart_d_clock(usec, who, proc) int usec, who; void (*proc) ();{ struct itimerval tim, otim; tim.it_interval.tv_usec = 0; tim.it_interval.tv_sec = 0; tim.it_value.tv_usec = usec % 1000000; tim.it_value.tv_sec = usec / 1000000; if (under_xview) notify_set_itimer_func(who, proc, ITIMER_REAL, &tim, ITIMER_NULL); else { void (*sav) (); setitimer(ITIMER_REAL, &tim, &otim); sav = signal(SIGALRM, proc); if (!sigsave) sigsave = sav; }}/*************************************************************************/stop_d_clock(who) int who;{ static Notify_value process_d_q(); if (under_xview) notify_set_itimer_func(who, process_d_q, ITIMER_REAL, ITIMER_NULL, ITIMER_NULL); else { signal(SIGALRM, sigsave); sigsave = NULL; }}static StrList *this_request = NULL;/*************************************************************************//* * The idea here is that xwaves can grab the information required to respond * to a caller before launching any asynchronous process needed to satisfy * the caller's request. When the asynchronous process causes its callback * to run, the result notice can finally be returned to the original caller. */void *in_a_ipc_dispatch(){ if (this_request) { Win_data *xs = (void *) this_request->data; this_request->data = NULL; return ((void *) xs); } else return (NULL);}/*************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -