📄 xipmsg.c
字号:
/* * xipmsg.c - IP Messenger 1.20 for X11 * Copyright (C) 1995, 1996 by candy */char rcsid_xipmsg[] = "$Id: xipmsg.c,v 3.7 1997/05/02 05:27:46 candy Exp candy $";#include <ctype.h>#include <math.h> /* floor() */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <X11/Intrinsic.h>#include <X11/StringDefs.h>#include <X11/Shell.h>#include <X11/Xatom.h>#include <X11/Xlocale.h>#include <X11/Xutil.h>#include <X11/cursorfont.h>#include <X11/keysym.h>#include <X11/Xaw/AsciiText.h>#include <X11/Xaw/Box.h>#include <X11/Xaw/Cardinals.h>#include <X11/Xaw/Command.h>#include <X11/Xaw/Dialog.h>#include <X11/Xaw/Form.h>#include <X11/Xaw/Label.h>#include <X11/Xaw/List.h>#include <X11/Xaw/MenuButton.h>#include <X11/Xaw/Paned.h>#include <X11/Xaw/Scrollbar.h>#include <X11/Xaw/SimpleMenu.h>#include <X11/Xaw/SmeBSB.h>#include <X11/Xaw/Toggle.h>#include <X11/Xaw/Viewport.h>#include <unistd.h> /* select() */#include <sys/time.h> /* setitimer() *//* includes below are order dependent */#include <sys/param.h> /* htons() */#include <sys/types.h> /* socket() */#include <sys/socket.h> /* socket() */#include <netinet/in.h> /* inet_addr() INADDR_ANY */#include <arpa/inet.h> /* inet_addr() */#include "xipmsg.h"#include "brocas.h"#include "db.h"#ifdef NO_STRTOUL#define strtoul(s,p,b) ((unsigned long)strtol(s,p,b))#endif#ifdef NO_MEMMOVE#define memmove(d,s,l) bcopy(s,d,l)#endif#ifdef SUNOS41X /* [ */static intatexit(void (*proc)(void)){ return on_exit((void (*)(int, caddr_t))proc, NULL);}/* atexit */#endif /* ] */#ifdef NO_ATEXIT /* [ */static void (*at_exit_proc)(void);static voidinttrap(void){ if (at_exit_proc != NULL) { at_exit_proc(); } exit(1);}/* inttrap */static intatexit(void (*proc)(void)){ at_exit_proc = proc; signal(SIGINT, inttrap); signal(SIGHUP, inttrap); signal(SIGTERM, inttrap); return 0;}/* atexit */#endif /* ] */#define NUMBER_OF_MENU 16 /* Don't forget change fallback_resources[] too.*/extern char *myname;static XtAppContext app_con;static Widget toplevel;static char last_msg[MESSAGE_MAX];static Pixmap last_icon;static Cursor csr_clock;static int iconified;static int pause_time = 500; /* milli-seconds */static int bogus_fix;static void send_dialog(Widget parent, const struct maddr_t *dstaddr, const char *to);/* * リストの改眶を手す。 */static intcount_list(const void * const *ls){ const void * const *mv = ls; while (*mv++ != NULL) ; return mv - 1 - ls;}/* count_list *//* * カンマで惰磊られた矢机误をリストに恃垂する。 */static char **cvs_list(const char *s){ char **ls = NULL; int n = 0; const char *p = s; while (strchr(p, ',') != NULL) { p = strchr(p, ',') + 1; n++; }/* while */ n++; ls = malloc(sizeof(*ls) * (n + 1)); if (ls != NULL) { char *buf = str_dup(s); if (buf != NULL) { char *mv = buf; int i; ls[0] = mv; for (i = 1; i < n; i++) { mv = strchr(mv, ','); *mv++ = '\0'; while (isascii(*mv) && isspace(*mv)) mv++; ls[i] = mv; }/* for */ ls[n] = NULL; } } return ls;}/* cvs_list */#define FROM_DB_MAX 64struct from_t { int fr_so; char fr_name[USERNAME_MAX + HOSTNAME_MAX]; struct sockaddr_in fr_addr; struct packet_t fr_pk; char fr_last_msg[MESSAGE_MAX]; /* 呵稿に流ったメッセ〖ジ */ unsigned int fr_x0, fr_y0; /* 呵介にダイアログを叫す疤弥 */ unsigned int fr_x, fr_y; /* 肌にダイアログを叫す疤弥 */ int fr_count; /* 倡いているダイアログの眶 */};static struct db_t *from_db;static intfrom_comp(const void *d_, const void *s_){ const struct from_t *d = d_, *s = s_; int cmp = strcmp(d->fr_name, s->fr_name); return cmp;}/* from_comp *//* * window 升は呵络 466 くらい */static struct from_t *from_install(const char *from){ static int lastx = 4, lasty = 4; struct from_t *fr = malloc(sizeof(*fr)); int wx = DisplayWidth(XtDisplay(toplevel), 0); int wy = DisplayHeight(XtDisplay(toplevel), 0); if (lastx >= wx - 300) lastx = lastx % (wx - 300); if (lasty >= wy - 160) lasty = lasty % (wy - 160); if (fr != NULL) { memset(fr, '\0', sizeof(*fr)); strncpyz(fr->fr_name, from, sizeof(fr->fr_name)); strcpy(fr->fr_last_msg, last_msg); fr->fr_x0 = lastx; fr->fr_y0 = lasty; fr->fr_x = lastx; fr->fr_y = lasty; fr->fr_count = 0; lastx += 256; db_install(from_db, fr); } return fr;}/* from_install */static struct from_t *from_lookup(const char *from){ struct from_t key, *fr; strncpyz(key.fr_name, from, sizeof(key.fr_name)); fr = db_lookup(from_db, &key); return fr;}/* from_lookup */static voidnext_pos(Dimension *nx, Dimension *ny){ static int lastx = 20, lasty = 20; int wx = DisplayWidth(XtDisplay(toplevel), 0); int wy = DisplayHeight(XtDisplay(toplevel), 0); if (lastx >= wx - 300) lastx = 20; if (lasty >= wy - 200) lasty = 20; *nx = lastx; *ny = lasty; lastx += 10; lasty += 100;}/* next_pos *//* * 笆布の from_*()では fr == NULL でもよい。 */static struct from_t *from_next_pos(struct from_t *fr, Dimension *nx, Dimension *ny){ int wy = DisplayHeight(XtDisplay(toplevel), 0); if (fr != NULL) { *nx = fr->fr_x; *ny = fr->fr_y; fr->fr_y += 100; if (fr->fr_y >= wy - 200) fr->fr_y = fr->fr_y0; } else { next_pos(nx, ny); } return fr;}/* from_next_pos */static char *from_last_msg(struct from_t *fr){ char *ret = NULL; if (fr != NULL) ret = fr->fr_last_msg; else ret = last_msg; return ret;}/* from_last_msg */static struct from_t *from_count_up(struct from_t *fr){ if (fr != NULL) fr->fr_count++; return fr;}/* from_count_up */static struct from_t *from_count_down(struct from_t *fr){ if (fr != NULL) { if (--fr->fr_count == 0) { fr->fr_x = fr->fr_x0; fr->fr_y = fr->fr_y0; } } return fr;}/* from_count_down *//* * */static voidiconify_action(Widget w, XEvent *event, String *params, Cardinal *num_params){ Display *d = XtDisplay(toplevel); Window win = XtWindow(toplevel); int scno = XScreenNumberOfScreen(XtScreen(w)); if (iconified) XMapWindow(d, win); else XIconifyWindow(d, win, scno); iconified = !iconified;}/* iconify_action *//* * 手慨ボタン */static voidanswer_proc(Widget w, XtPointer closure, XtPointer call_data){ struct maddr_t *replyto = closure; Widget from = XtNameToWidget(XtParent(w), "from"); if (from != NULL) { String to; XtVaGetValues(from, XtNlabel, &to, NULL);#if 1 /* answer箕に苞脱する怠墙の纳裁 sakane@NES [ */ { struct from_t *fr = from_lookup(to); if (fr != NULL) { char answer_string[MESSAGE_MAX]; char *p, *ap = answer_string; String from_msg; Widget dialog = XtParent(w); XtVaGetValues(dialog, XtNlabel, &from_msg, NULL); memset(answer_string, '\0', sizeof(answer_string)); *ap = '>'; for (p = (char *)from_msg;*p != '\0' && ap + 1 < &answer_string[COUNTOF(answer_string)];++p) { *++ap = *p; if (*p == '\n') { if (*(p + 1) != '\0') *++ap = '>'; } } ap[1] = '\0'; strncpyz(fr->fr_last_msg, answer_string, sizeof(fr->fr_last_msg)); } }#endif /* ] */ send_dialog(w, replyto, to); } else { fprintf(stderr, "%s: [answer] cannot get `from' widget.\n", myname); }}/* answer_proc *//* * Done または Cancel ボタン */static voiddone_proc(Widget w, XtPointer closure, XtPointer call_data){ if (bogus_fix) XtPopdown(XtParent(XtParent(w))); else XtDestroyWidget(XtParent(XtParent(w)));}/* done_proc *//* * destroyCallback */static voiddestroy_proc(Widget w, XtPointer closure, XtPointer call_data){ XtFree(closure);}/* destroy_proc *//* * destroyCallback */static voidfrom_free_proc(Widget w, XtPointer closure, XtPointer call_data){ struct from_t *fr = closure; from_count_down(fr);}/* from_free_proc *//* * セレクション [ */#undef SELECT_TOGGLEstatic char selected_string[MESSAGE_MAX];/* * ペ〖スト(?)の妥滇があった。 */static Booleanconvert_selection(Widget w, Atom *selection, Atom *target, Atom *type_return, XtPointer *value_return, unsigned long *length_return, int *format_return){ XTextProperty ct; Display *d = XtDisplay(w); char *v = selected_string; XmbTextListToTextProperty(d, &v, 1, XCompoundTextStyle, &ct); *type_return = ct.encoding; *length_return = ct.nitems; *value_return = ct.value; *format_return = ct.format; return True;}/* convert_selection */static voidlose_selection(Widget w, Atom *selection){ return;}/* lose_selection */static voidown_selection(Widget w, XtPointer closure, XtPointer call_data){ Time time = XtLastTimestampProcessed(XtDisplay(w)); XtOwnSelection(w, XA_PRIMARY, time, convert_selection, lose_selection, NULL);}/* own_selection *//* ] セレクション *//* * コピ〖ボタン */static voidselect_proc(Widget w, XtPointer closure, XtPointer call_data){ Widget dialog = XtParent(w); String str; char *p; XtVaGetValues(dialog, XtNlabel, &str, NULL); strncpyz(selected_string, str, sizeof(selected_string)); p = strrchr(selected_string, '\n'); if (p != NULL) { *p = '\0'; if (*--p == '\n') *p = '\0'; } own_selection(toplevel, NULL, NULL);}/* select_proc *//* * */static char *cryption(char *str, int decode_flag){ unsigned char *p = (unsigned char *)str; while (*p != '\0') { if (*p != '\n' && *p != 0xff - '\n')
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -