📄 xipmsg.c
字号:
int ksym; }; static struct kw_t kw[] = { {"Up", XK_Up}, {"Down", XK_Down}, {"Page_Up", XK_Page_Up}, {"Page_Down", XK_Page_Down}, {"Home", XK_Home}, {"End", XK_End}, {NULL, 0}, }; struct kw_t *p = kw; while (p->name != NULL && strcmp(p->name, arg) != 0) p++; if (p->name != NULL) { do_control_key(list, p->ksym); err = 0; } if (err < 0) fprintf(stderr, "%s: bad parameter for key_named_action.\n", arg); } }}/* list_key_named_action *//* * リストでキ〖が病されたアクション * ˇカ〖ソルキ〖でスクロ〖ル * ˇ片矢机で、マッチした疥に若ぶ */static voidlist_key_action(Widget list, XEvent *event, String *params, Cardinal *num_params){ static Time last_time; if (XtClass(list) == listWidgetClass && event->type == KeyPress) { XKeyEvent *ev = &event->xkey; int multi_event_time = XtGetMultiClickTime(XtDisplay(list)); /* milli-sec */ char kbuf[32]; KeySym ksym; int len = XLookupString(ev, kbuf, sizeof(kbuf) - 1, &ksym, NULL); multi_event_time *= 2; /* キ〖タイプ庐刨はクリック庐刨より觅いので */ kbuf[len] = '\0'; switch (ksym) { case XK_Up: case XK_Down: case XK_Home: case XK_End: case XK_Page_Up: case XK_Page_Down: do_control_key(list, ksym); break; default: if (len != 0) { static char match_str[32]; static int match_len; if (ev->time - last_time >= multi_event_time) { match_len = 0; match_str[0] = '\0'; } if (strlen(match_str) + len < sizeof(match_str) - 1) { strcat(match_str, kbuf); list_select_match(list, match_str); } } break; }/* switch */ last_time = ev->time; }}/* list_key_action *//* ] List Widget の拎侯 *//* * 叹涟リストにキ〖イベントが葡いたアクション */static voidcall_name_list_action(Widget w, XEvent *event, String *params, Cardinal *num_params){ w = XtNameToWidget(toplevel, "*name_list"); if (w != NULL && XtClass(w) == listWidgetClass) { list_key_action(w, event, params, num_params); }}/* call_name_list_action *//* * 叹涟リストを构糠する。 */static intrefresh_name_list(Widget list){ ns_clear(); list_clear(list); send_IPMSG_BR_ENTRY(); return 0;}/* refresh_name_list *//* * ゾ〖ンリストをクリックされた借妄。 */static voidget_zone_proc(Widget w, XtPointer closure, XtPointer call_data){ Widget name_list = (Widget)closure; refresh_name_list(name_list);}/* get_zone_proc *//* * 极尸の叹涟を斧えなくするボタン。 */static voiddisable_proc(Widget w, XtPointer closure, XtPointer call_data){ Boolean state; XtVaGetValues(w, XtNstate, &state, NULL); XDefineCursor(XtDisplay(w), XtWindow(w), csr_clock); XDefineCursor(XtDisplay(toplevel), XtWindow(toplevel), csr_clock); XFlush(XtDisplay(w)); bro_set_disable(state); XUndefineCursor(XtDisplay(toplevel), XtWindow(toplevel)); XUndefineCursor(XtDisplay(w), XtWindow(w));}/* disable_proc *//* * 姜位 */static voidquit_proc(Widget w, XtPointer closure, XtPointer call_data){ exit(0);}/* quit_proc *//* * ファイル *source に掐蜗があった箕钙び叫される。 */static voidinput_proc(XtPointer closure, int *source, XtInputId *id){ bro_recv_packet(*source);}/* input_proc *//* * タイムアウト借妄。 */static voidtimeout_proc(XtPointer p1, XtIntervalId* id){ XtAppContext app_con = p1;#if 0 static Widget icon_label; static int done, count, status = -1; static Pixmap icons[2]; if (!done) { done = 1; icon_label = XtNameToWidget(toplevel, "*icon_label"); if (icon_label != NULL) { Widget icon_label2; XtVaGetValues(icon_label, XtNbitmap, &icons[0], NULL); icon_label2 = XtNameToWidget(toplevel, "*icon_label2"); if (icon_label2 != NULL) { XtVaGetValues(icon_label2, XtNbitmap, &icons[1], NULL); status = 1; } } } if (status >= 0) { if (++count == 10) { count = 0; XtVaSetValues(icon_label, XtNbitmap, icons[status], NULL); status = (status + 1) % COUNTOF(icons); } }#endif bro_job(); XtAppAddTimeOut(app_con, pause_time, timeout_proc, app_con);}/* timeout_proc *//* * 部もイベントが痰い箕钙ばれる。 */static Booleanwork_proc(XtPointer closure){ bro_work(); return True; /* True -> remove proc */}/* work_proc *//* * アクション *//* * 戮の Command widget のコ〖ルバックを钙び叫す、アクション借妄ル〖チン。 * 1. イベントのあったウィジェットから、科をたどって Dialog widget を玫す。 * 2. その Dialog widget を弹爬に params の叹涟の widget を玫す。 * 3. その widget の set() notify() unset() アクションを钙び叫す。 */static voiddirect_call_action(Widget w, XEvent *event, String *params, Cardinal *num_params){ Widget dialog = w; while (dialog != NULL && XtClass(dialog) != dialogWidgetClass) dialog = XtParent(dialog); if (dialog == NULL) dialog = toplevel; if (params != NULL) { String name = *params; Widget command = XtNameToWidget(dialog, name); if (command != NULL) { if (XtClass(command) == commandWidgetClass) { XtCallActionProc(command, "set", event, NULL, ZERO); XtCallActionProc(command, "notify", event, NULL, ZERO); XtCallActionProc(command, "unset", event, NULL, ZERO); } else { fprintf(stderr, "%s:direct_call_action: %s: not Command widget.\n", myname, name); } } else { fprintf(stderr, "%s:direct_call_action: %s: unknown widget.\n", myname, name); } } else { fprintf(stderr, "%s:direct_call_action: no arg.\n", myname); }}/* direct_call_action *//* * disable は Command じゃないので、direct_call_action が蝗えない。 */static voiddisable_action(Widget w, XEvent *event, String *params, Cardinal *num_params){ Widget disable = XtNameToWidget(toplevel, "*disable"); if (disable != NULL) { Boolean state; String action; XtVaGetValues(disable, XtNstate, &state, NULL); action = state ? "unset" : "set"; XtCallActionProc(disable, action, event, params, *num_params); XtCallActionProc(disable, "notify", event, params, *num_params); } else fprintf(stderr, "%s: disable toggle not found.\n", myname);}/* disable_action *//* * IP Messenger のイベントの借妄 */static voidipmsg_notify(enum bro_event_t evt, void *closure, void *call_data){ switch (evt) { case BRO_EV_START_WORK_PROC: { XtAppContext app_con = closure; XtAppAddWorkProc(app_con, work_proc, app_con); } break; case BRO_EV_LIST_CHANGED: { Widget name_list = closure; char **ls, *name = NULL; int n; XawListReturnStruct *np = XawListShowCurrent(name_list); if (np->list_index != XAW_LIST_NONE) { name = str_dup(np->string); } ls = ns_list(); n = count_list((void *)ls); XawListChange(name_list, ls, n, 0, True); if (name != NULL) { list_select_match(name_list, name); free(name); } } break; case BRO_EV_RECV_MESSAGE: { struct msg_data_t *md = call_data; struct maddr_t *rp = md->md_replyto; recv_dialog(md->md_msg, md->md_from, md->md_icon, rp, md->md_opt, md->md_pkno); } break; case BRO_EV_RECV_ACK: if (debug_flag & 1) fprintf(stderr, "%s に叫したメッセ〖ジは葡いたようです。\n", (char *)call_data); break; case BRO_EV_NO_ACK: error_dialog(toplevel, "not_sent"); if (debug_flag & 1) fprintf(stderr, "%s :メッセ〖ジは葡かなかったようです。\n", (char *)call_data); break; case BRO_EV_MAX: break; }/* switch */}/* ipmsg_notify *//* * */static voidexit_proc(void){ send_IPMSG_BR_EXIT();}/* exit_proc */#define DEFSTR(name, class, default) {#name, class, XtRString, sizeof(String), XtOffsetOf(struct appr, name), XtRString, (default)}#define DEFINT(name, class, default) {#name, class, XtRInt, sizeof(int), XtOffsetOf(struct appr, name), XtRImmediate, (XtPointer)(default)}#define DEFBOOL(name, class, default) {#name, class, XtRBoolean, sizeof(Boolean), XtOffsetOf(struct appr, name), XtRImmediate, (XtPointer)(default)}#define TITLE "XIP Messenger V0.8086"/* * */intmain(int argc, char *argv[]){ int ex = 1; static String fallback_resources[] = {#include "xipmsg.ad.h" NULL, }; static XtActionsRec actions[] = { {"direct_call_action", direct_call_action}, {"call_name_list_action", call_name_list_action}, {"iconify_action", iconify_action}, {"disable_action", disable_action}, {"list_key_named_action", list_key_named_action}, }; static XrmOptionDescRec options[] = { /* {option, specifier, argKind, value} */ {"-bogus_fix", ".bogusfix", XrmoptionNoArg, "True"}, {"-broadcast", ".broadcast", XrmoptionSepArg, NULL}, {"-disable", ".disable", XrmoptionNoArg, "True"}, {"-debug", ".debug", XrmoptionSepArg, NULL}, {"-name", ".name", XrmoptionSepArg, NULL}, {"-port", ".port", XrmoptionSepArg, NULL}, }; struct appr { Boolean bogusfix; String broadcast; String debug; Boolean disable; String name; String port; } app_resources; static XtResource resources[] = { /* resource_{name, class, type, size}, */ /* resource_offset, default_type, default_addr */ DEFBOOL(bogusfix, "Bogusfix", False), DEFSTR(broadcast, "Broadcast", "255.255.255.255"), DEFSTR(debug, "Debug", NULL), DEFBOOL(disable, "Disable", False), DEFSTR(name, "Name", NULL), DEFSTR(port, "Port", NULL), }; static char usage_msg[] = "usage: %s " "[-bogus_fix][-disable]" "[-broadcast xx.xx.xx.xx][-debug n]" "[-port n][-name str]" "[Xtoolkit options]" "\n"; myname = argv[0]; XtSetLanguageProc(NULL, NULL, NULL); toplevel = XtVaAppInitialize(&app_con, "XIpmsg", options, XtNumber(options), &argc, argv, fallback_resources, NULL); if (argc > 1) { fprintf(stderr, usage_msg, myname, argv[1]); } else { int port = IPMSG_DEFAULT_PORT, bro_so; char **bros; char *name, entity_name[USERNAME_MAX], hostname[HOSTNAME_MAX]; XtVaGetApplicationResources(toplevel, &app_resources, resources, XtNumber(resources), NULL); XtAppAddActions(app_con, actions, XtNumber(actions)); bogus_fix = app_resources.bogusfix; if (app_resources.debug) debug_flag = strtol(app_resources.debug, NULL, 0); if (app_resources.disable) bro_set_disable(True); if (app_resources.port != NULL) port = strtol(app_resources.port, NULL, 0); if (app_resources.name != NULL) name = app_resources.name; else name = getenv("USER"); if (name == NULL) name = "anonymous"; bros = cvs_list(app_resources.broadcast); strncpyz(entity_name, name, sizeof(entity_name)); gethostname(hostname, sizeof(hostname)); hostname[sizeof(hostname) - 1] = '\0'; if (strchr(hostname, '.') != NULL) *strchr(hostname, '.') = '\0'; bro_so = bro_init(port, entity_name, hostname, (void *)bros); if (bro_so < 0) { fprintf(stderr, "%s: failed to initialize.\n", myname); perror("bro_init"); } else if ((from_db = db_new(FROM_DB_MAX, from_comp)) == NULL) fprintf(stderr, "%s: malloc failed.\n", myname); else { Widget level0, main1, main2, commands, disable; Widget name_view, name_list; ex = 0; csr_clock = XCreateFontCursor(XtDisplay(toplevel), XC_watch); level0 = XtVaCreateManagedWidget("level0", panedWidgetClass, toplevel, NULL); main1 = XtVaCreateManagedWidget("main1", formWidgetClass, level0, NULL); main2 = XtVaCreateManagedWidget("main2", formWidgetClass, level0, NULL); commands = XtVaCreateManagedWidget("commands", panedWidgetClass, main1, NULL); XtVaCreateManagedWidget("icon_label", labelWidgetClass, main1, NULL); XtVaCreateManagedWidget("icon_label2", labelWidgetClass, main1, NULL); name_view = XtVaCreateManagedWidget("name_view", viewportWidgetClass, main2, NULL); name_list = XtVaCreateManagedWidget("name_list", listWidgetClass, name_view, NULL); XawDialogAddButton(commands, "quit", quit_proc, NULL); XawDialogAddButton(commands, "get_zone", get_zone_proc, name_list); XawDialogAddButton(commands, "compose", compose_proc, name_list); disable = XtVaCreateManagedWidget("disable", toggleWidgetClass, commands, XtNstate, app_resources.disable, NULL); XtAddCallback(disable, XtNcallback, disable_proc, NULL); XtRealizeWidget(toplevel); XStoreName(XtDisplay(toplevel), XtWindow(toplevel), TITLE); XSetIconName(XtDisplay(toplevel), XtWindow(toplevel), "xipmsg"); XtAppAddTimeOut(app_con, pause_time, timeout_proc, app_con); XtAppAddInput(app_con, bro_so, (XtPointer)XtInputReadMask, input_proc, NULL); bro_add_callback(BRO_EV_LIST_CHANGED, ipmsg_notify, name_list); bro_add_callback(BRO_EV_RECV_MESSAGE, ipmsg_notify, NULL); bro_add_callback(BRO_EV_RECV_ACK, ipmsg_notify, NULL); bro_add_callback(BRO_EV_NO_ACK, ipmsg_notify, NULL); bro_add_callback(BRO_EV_START_WORK_PROC, ipmsg_notify, app_con); refresh_name_list(name_list); atexit(exit_proc); XtAppMainLoop(app_con); } } return ex;}/* main */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -