void menu_create(Widget w, XEvent *event, String *actargs, Cardinal *count) { int line; int i; uschar *s; XawTextPosition p; Widget src, menu_line, item_1, item_2, item_3, item_4, item_5, item_6, item_7, item_8, item_9, item_10, item_11, item_12, item_13; XtTranslations menu_trans = XtParseTranslationTable( "<EnterWindow>: highlight()\n\ <LeaveWindow>: unhighlight()\n\ <BtnMotion>: highlight()\n\ <BtnUp>: MenuPopdown()notify()unhighlight()\n\ "); actargs = actargs; /* Keep picky compilers happy */ count = count; /* Get the sink and source and the current text pointer */ queue_get_arg[0].value = (XtArgVal)(&queue_text_sink); queue_get_arg[1].value = (XtArgVal)(&src); queue_get_arg[2].value = (XtArgVal)(&s); XtGetValues(w, queue_get_arg, 3); /* Find the line number of the pointer in the window, and the character offset of the top lefthand of the window. */ line = (event->xbutton).y / XawTextSinkMaxHeight(queue_text_sink, 1); p = XawTextTopPosition(w); /* Find the start of the line on which the button was clicked. */ i = line; while (i-- > 0) { while (s[p] != 0 && s[p++] != '\n'); } /* Now pointing either at 0 or 1st uschar after \n, or very 1st uschar. If 0, the click was beyond the end of the data; just set up a dummy menu. (Not easy to ignore as several actions are specified for the mouse click and it expects this one to set up a menu.) If on a continuation line, move back to the main line. */ if (s[p] == 0) { menushell_arg[0].value = (XtArgVal)"No message selected"; menushell = XtCreatePopupShell("menu", simpleMenuWidgetClass, queue_widget, menushell_arg, XtNumber(menushell_arg)); XtAddCallback(menushell, "popdownCallback", popdownAction, NULL); xs_SetValues(menushell, 2, "cursor", XCreateFontCursor(X_display, XC_arrow), "translations", menu_trans); /* To keep the widgets in XFree86 happy, we have to create at least one menu item, it seems. (Openwindows doesn't mind a menu with no items.) Otherwise there's a complaint about a zero width menu, and a crash. */ menu_line = XtCreateManagedWidget("line", smeLineObjectClass, menushell, NULL, 0); item_99_arg[0].value = (XtArgVal)menu_line; (void)XtCreateManagedWidget("item99", smeBSBObjectClass, menushell, item_99_arg, XtNumber(item_99_arg)); highlighted_x = -1; return; } while (p > 0 && s[p+11] == ' ') { line--; p--; while (p > 0 && s[p-1] != '\n') p--; } /* Now pointing at first character of a main line. */ Ustrncpy(message_id, s+p+11, MESSAGE_ID_LENGTH); message_id[MESSAGE_ID_LENGTH] = 0; /* Highlight the line being menued, and save its parameters so that it can be de-highlighted at popdown. */ highlighted_start = highlighted_end = p; while (s[highlighted_end] != '\n') highlighted_end++; highlighted_x = 17; highlighted_y = line * XawTextSinkMaxHeight(queue_text_sink, 1) + 2; XawTextSinkDisplayText(queue_text_sink, highlighted_x, highlighted_y, highlighted_start, highlighted_end, 1); /* Create the popup shell and the other widgets that comprise the menu. Set the translations and pointer shape, and add the callback pointers. */ menushell_arg[0].value = (XtArgVal)message_id; menushell = XtCreatePopupShell("menu", simpleMenuWidgetClass, queue_widget, menushell_arg, XtNumber(menushell_arg)); XtAddCallback(menushell, "popdownCallback", popdownAction, NULL); xs_SetValues(menushell, 2, "cursor", XCreateFontCursor(X_display, XC_arrow), "translations", menu_trans); menu_line = XtCreateManagedWidget("line", smeLineObjectClass, menushell, NULL, 0); item_1_arg[0].value = (XtArgVal)menu_line; item_1 = XtCreateManagedWidget("item1", smeBSBObjectClass, menushell, item_1_arg, XtNumber(item_1_arg)); XtAddCallback(item_1, "callback", msglogAction, (XtPointer)message_id); item_2_arg[0].value = (XtArgVal)item_1; item_2 = XtCreateManagedWidget("item2", smeBSBObjectClass, menushell, item_2_arg, XtNumber(item_2_arg)); XtAddCallback(item_2, "callback", headersAction, (XtPointer)message_id); item_3_arg[0].value = (XtArgVal)item_2; item_3 = XtCreateManagedWidget("item3", smeBSBObjectClass, menushell, item_3_arg, XtNumber(item_3_arg)); XtAddCallback(item_3, "callback", bodyAction, (XtPointer)message_id); item_4_arg[0].value = (XtArgVal)item_3; item_4 = XtCreateManagedWidget("item4", smeBSBObjectClass, menushell, item_4_arg, XtNumber(item_4_arg)); XtAddCallback(item_4, "callback", deliverAction, (XtPointer)message_id); item_5_arg[0].value = (XtArgVal)item_4; item_5 = XtCreateManagedWidget("item5", smeBSBObjectClass, menushell, item_5_arg, XtNumber(item_5_arg)); XtAddCallback(item_5, "callback", freezeAction, (XtPointer)message_id); item_6_arg[0].value = (XtArgVal)item_5; item_6 = XtCreateManagedWidget("item6", smeBSBObjectClass, menushell, item_6_arg, XtNumber(item_6_arg)); XtAddCallback(item_6, "callback", thawAction, (XtPointer)message_id); item_7_arg[0].value = (XtArgVal)item_6; item_7 = XtCreateManagedWidget("item7", smeBSBObjectClass, menushell, item_7_arg, XtNumber(item_7_arg)); XtAddCallback(item_7, "callback", giveupAction, (XtPointer)message_id); item_8_arg[0].value = (XtArgVal)item_7; item_8 = XtCreateManagedWidget("item8", smeBSBObjectClass, menushell, item_8_arg, XtNumber(item_8_arg)); XtAddCallback(item_8, "callback", removeAction, (XtPointer)message_id); item_9_arg[0].value = (XtArgVal)item_8; item_9 = XtCreateManagedWidget("item9", smeBSBObjectClass, menushell, item_9_arg, XtNumber(item_9_arg)); item_10_arg[0].value = (XtArgVal)item_9; item_10 = XtCreateManagedWidget("item10", smeBSBObjectClass, menushell, item_10_arg, XtNumber(item_10_arg)); XtAddCallback(item_10, "callback", addrecipAction, (XtPointer)message_id); item_11_arg[0].value = (XtArgVal)item_10; item_11 = XtCreateManagedWidget("item11", smeBSBObjectClass, menushell, item_11_arg, XtNumber(item_11_arg)); XtAddCallback(item_11, "callback", markdelAction, (XtPointer)message_id); item_12_arg[0].value = (XtArgVal)item_11; item_12 = XtCreateManagedWidget("item12", smeBSBObjectClass, menushell, item_12_arg, XtNumber(item_12_arg)); XtAddCallback(item_12, "callback", markalldelAction, (XtPointer)message_id); item_13_arg[0].value = (XtArgVal)item_12; item_13 = XtCreateManagedWidget("item13", smeBSBObjectClass, menushell, item_13_arg, XtNumber(item_13_arg)); XtAddCallback(item_13, "callback", editsenderAction, (XtPointer)message_id); /* Arrange that the menu pops up with the first item selected. */ xs_SetValues(menushell, 1, "popupOnEntry", item_1); /* Flag that the menu is up to suppress queue updates. */ menu_is_up = TRUE; }
/* * Implementation */ static void XawAsciiInitialize(Widget request, Widget cnew, ArgList args, Cardinal *num_args) { AsciiWidget w = (AsciiWidget)cnew; int i; int tabs[TAB_COUNT], tab; MultiSinkObject sink; /* superclass Initialize can't set the following, * as it didn't know the source or sink when it was called */ if (XtHeight(request) == DEFAULT_TEXT_HEIGHT) XtHeight(cnew) = DEFAULT_TEXT_HEIGHT; /* This is the main change for internationalization */ if (w->simple.international == True) { /* The multi* are international */ if (w->text.sink == NULL) w->text.sink = XtCreateWidget("textSink", multiSinkObjectClass, cnew, args, *num_args); else if (!XtIsSubclass(w->text.sink, multiSinkObjectClass)) XtError("Sink object is not a subclass of multiSink"); if (w->text.source == NULL) w->text.source = XtCreateWidget("textSource", multiSrcObjectClass, cnew, args, *num_args); else if (!XtIsSubclass(w->text.source, multiSrcObjectClass)) XtError("Source object is not a subclass of multiSrc"); #ifndef OLDXAW else _XawSourceAddText(w->text.source, cnew); #endif } else { if (w->text.sink == NULL) w->text.sink = XtCreateWidget("textSink", asciiSinkObjectClass, cnew, args, *num_args); else if (!XtIsSubclass(w->text.source, asciiSinkObjectClass)) XtError("Sink object is not a subclass of asciiSink"); if (w->text.source == NULL) w->text.source = XtCreateWidget("textSource", asciiSrcObjectClass, cnew, args, *num_args); else if (!XtIsSubclass(w->text.source, asciiSrcObjectClass)) XtError("Source object is not a subclass of asciiSrc"); #ifndef OLDXAW else _XawSourceAddText(w->text.source, cnew); #endif } if (XtHeight(w) == DEFAULT_TEXT_HEIGHT) XtHeight(w) = VMargins(w) + XawTextSinkMaxHeight(w->text.sink, 1); for (i = 0, tab = 0; i < TAB_COUNT; i++) tabs[i] = (tab += 8); XawTextSinkSetTabs(w->text.sink, TAB_COUNT, tabs); XawTextDisableRedisplay(cnew); XawTextEnableRedisplay(cnew); _XawImRegister(cnew); /* If we are using a MultiSink we need to tell the input method stuff */ if (w->simple.international == True) { Arg list[4]; Cardinal ac = 0; sink = (MultiSinkObject)w->text.sink; XtSetArg(list[ac], XtNfontSet, sink->multi_sink.fontset); ac++; XtSetArg(list[ac], XtNinsertPosition, w->text.insertPos); ac++; XtSetArg(list[ac], XtNforeground, sink->text_sink.foreground); ac++; XtSetArg(list[ac], XtNbackground, sink->text_sink.background); ac++; _XawImSetValues(cnew, list, ac); } }