/* simple_popup.c -- demonstrate how to use a simple popup menu. ** Create a main window that contains a DrawingArea widget, which ** displays a popup menu when the user presses the third mouse button. */ #include #include #include #include #include #include Display *display ; Widget popup_menu ; /* * xev - event diagnostics * * $XConsortium: xev.c,v 1.14 91/05/04 23:15:11 keith Exp $ * * Copyright 1988 Massachusetts Institute of Technology * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. M.I.T. makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * Author: Jim Fulton, MIT X Consortium */ static char *Yes = "YES"; static char *No = "NO"; static char *Unknown = "unknown"; static void prologue (const XEvent *eventp, char *event_name) { const XAnyEvent *e = (const XAnyEvent *) eventp; fprintf(stderr, "\n%s event, serial %ld, synthetic %s, window 0x%lx,\n", event_name, e->serial, e->send_event ? Yes : No, e->window); return; } static void do_KeyPress (const XEvent *eventp) { const XKeyEvent *e = (const XKeyEvent *) eventp; KeySym ks; char *ksname; int nbytes; char str[256+1]; nbytes = XLookupString ((XKeyEvent *)e, str, 256, &ks, NULL); if (ks == NoSymbol) ksname = "NoSymbol"; else if (!(ksname = XKeysymToString (ks))) ksname = "(no name)"; fprintf(stderr, " root 0x%lx, subw 0x%lx, time %lu, (%d,%d), root:(%d,%d),\n", e->root, e->subwindow, e->time, e->x, e->y, e->x_root, e->y_root); fprintf(stderr, " state 0x%x, keycode %u (keysym 0x%lx, %s), same_screen %s,\n", e->state, e->keycode, ks, ksname, e->same_screen ? Yes : No); if (nbytes < 0) nbytes = 0; if (nbytes > 256) nbytes = 256; str[nbytes] = '\0'; fprintf(stderr, " XLookupString gives %d characters: \"%s\"\n", nbytes, str); return; } static void do_KeyRelease (const XEvent *eventp) { do_KeyPress (eventp); /* since it has the same info */ return; } static void do_ButtonPress (const XEvent *eventp) { const XButtonEvent *e = (const XButtonEvent *) eventp; fprintf(stderr, " root 0x%lx, subw 0x%lx, time %lu, (%d,%d), root:(%d,%d),\n", e->root, e->subwindow, e->time, e->x, e->y, e->x_root, e->y_root); fprintf(stderr, " state 0x%x, button %u, same_screen %s\n", e->state, e->button, e->same_screen ? Yes : No); return; } static void do_ButtonRelease (const XEvent *eventp) { do_ButtonPress (eventp); /* since it has the same info */ return; } static void do_MotionNotify (const XEvent *eventp) { const XMotionEvent *e = (const XMotionEvent *) eventp; fprintf(stderr, " root 0x%lx, subw 0x%lx, time %lu, (%d,%d), root:(%d,%d),\n", e->root, e->subwindow, e->time, e->x, e->y, e->x_root, e->y_root); fprintf(stderr, " state 0x%x, is_hint %u, same_screen %s\n", e->state, e->is_hint, e->same_screen ? Yes : No); return; } static void do_EnterNotify (const XEvent *eventp) { const XCrossingEvent *e = (const XCrossingEvent *) eventp; char *mode, *detail; char dmode[10], ddetail[10]; switch (e->mode) { case NotifyNormal: mode = "NotifyNormal"; break; case NotifyGrab: mode = "NotifyGrab"; break; case NotifyUngrab: mode = "NotifyUngrab"; break; case NotifyWhileGrabbed: mode = "NotifyWhileGrabbed"; break; default: mode = dmode, sprintf (dmode, "%u", e->mode); break; } switch (e->detail) { case NotifyAncestor: detail = "NotifyAncestor"; break; case NotifyVirtual: detail = "NotifyVirtual"; break; case NotifyInferior: detail = "NotifyInferior"; break; case NotifyNonlinear: detail = "NotifyNonlinear"; break; case NotifyNonlinearVirtual: detail = "NotifyNonlinearVirtual"; break; case NotifyPointer: detail = "NotifyPointer"; break; case NotifyPointerRoot: detail = "NotifyPointerRoot"; break; case NotifyDetailNone: detail = "NotifyDetailNone"; break; default: detail = ddetail; sprintf (ddetail, "%u", e->detail); break; } fprintf(stderr, " root 0x%lx, subw 0x%lx, time %lu, (%d,%d), root:(%d,%d),\n", e->root, e->subwindow, e->time, e->x, e->y, e->x_root, e->y_root); fprintf(stderr, " mode %s, detail %s, same_screen %s,\n", mode, detail, e->same_screen ? Yes : No); fprintf(stderr, " focus %s, state %u\n", e->focus ? Yes : No, e->state); return; } static void do_LeaveNotify (const XEvent *eventp) { do_EnterNotify (eventp); /* since it has same information */ return; } static void do_FocusIn (const XEvent *eventp) { const XFocusChangeEvent *e = (const XFocusChangeEvent *) eventp; char *mode, *detail; char dmode[10], ddetail[10]; switch (e->mode) { case NotifyNormal: mode = "NotifyNormal"; break; case NotifyGrab: mode = "NotifyGrab"; break; case NotifyUngrab: mode = "NotifyUngrab"; break; case NotifyWhileGrabbed: mode = "NotifyWhileGrabbed"; break; default: mode = dmode, sprintf (dmode, "%u", e->mode); break; } switch (e->detail) { case NotifyAncestor: detail = "NotifyAncestor"; break; case NotifyVirtual: detail = "NotifyVirtual"; break; case NotifyInferior: detail = "NotifyInferior"; break; case NotifyNonlinear: detail = "NotifyNonlinear"; break; case NotifyNonlinearVirtual: detail = "NotifyNonlinearVirtual"; break; case NotifyPointer: detail = "NotifyPointer"; break; case NotifyPointerRoot: detail = "NotifyPointerRoot"; break; case NotifyDetailNone: detail = "NotifyDetailNone"; break; default: detail = ddetail; sprintf (ddetail, "%u", e->detail); break; } fprintf(stderr, " mode %s, detail %s\n", mode, detail); return; } static void do_FocusOut (const XEvent *eventp) { do_FocusIn (eventp); /* since it has same information */ return; } static void do_KeymapNotify (const XEvent *eventp) { const XKeymapEvent *e = (const XKeymapEvent *) eventp; int i; fprintf(stderr, " keys: "); for (i = 0; i < 32; i++) { if (i == 16) fprintf(stderr, "\n "); fprintf(stderr, "%-3u ", (unsigned int) e->key_vector[i]); } fprintf(stderr, "\n"); return; } static void do_Expose (const XEvent *eventp) { const XExposeEvent *e = (const XExposeEvent *) eventp; fprintf(stderr, " (%d,%d), width %d, height %d, count %d\n", e->x, e->y, e->width, e->height, e->count); return; } static void do_GraphicsExpose (const XEvent *eventp) { const XGraphicsExposeEvent *e = (const XGraphicsExposeEvent *) eventp; char *m; char mdummy[10]; switch (e->major_code) { case X_CopyArea: m = "CopyArea"; break; case X_CopyPlane: m = "CopyPlane"; break; default: m = mdummy; sprintf (mdummy, "%d", e->major_code); break; } fprintf(stderr, " (%d,%d), width %d, height %d, count %d,\n", e->x, e->y, e->width, e->height, e->count); fprintf(stderr, " major %s, minor %d\n", m, e->minor_code); return; } static void do_NoExpose (const XEvent *eventp) { const XNoExposeEvent *e = (const XNoExposeEvent *) eventp; char *m; char mdummy[10]; switch (e->major_code) { case X_CopyArea: m = "CopyArea"; break; case X_CopyPlane: m = "CopyPlane"; break; default: m = mdummy; sprintf (mdummy, "%d", e->major_code); break; } fprintf(stderr, " major %s, minor %d\n", m, e->minor_code); return; } static void do_VisibilityNotify (const XEvent *eventp) { const XVisibilityEvent *e = (const XVisibilityEvent *) eventp; char *v; char vdummy[10]; switch (e->state) { case VisibilityUnobscured: v = "VisibilityUnobscured"; break; case VisibilityPartiallyObscured: v = "VisibilityPartiallyObscured"; break; case VisibilityFullyObscured: v = "VisibilityFullyObscured"; break; default: v = vdummy; sprintf (vdummy, "%d", e->state); break; } fprintf(stderr, " state %s\n", v); return; } static void do_CreateNotify (const XEvent *eventp) { const XCreateWindowEvent *e = (const XCreateWindowEvent *) eventp; fprintf(stderr, " parent 0x%lx, window 0x%lx, (%d,%d), width %d, height %d\n", e->parent, e->window, e->x, e->y, e->width, e->height); fprintf(stderr, "border_width %d, override %s\n", e->border_width, e->override_redirect ? Yes : No); return; } static void do_DestroyNotify (const XEvent *eventp) { const XDestroyWindowEvent *e = (const XDestroyWindowEvent *) eventp; fprintf(stderr, " event 0x%lx, window 0x%lx\n", e->event, e->window); return; } static void do_UnmapNotify (const XEvent *eventp) { const XUnmapEvent *e = (const XUnmapEvent *) eventp; fprintf(stderr, " event 0x%lx, window 0x%lx, from_configure %s\n", e->event, e->window, e->from_configure ? Yes : No); return; } static void do_MapNotify (const XEvent *eventp) { const XMapEvent *e = (const XMapEvent *) eventp; fprintf(stderr, " event 0x%lx, window 0x%lx, override %s\n", e->event, e->window, e->override_redirect ? Yes : No); return; } static void do_MapRequest (const XEvent *eventp) { const XMapRequestEvent *e = (const XMapRequestEvent *) eventp; fprintf(stderr, " parent 0x%lx, window 0x%lx\n", e->parent, e->window); return; } static void do_ReparentNotify (const XEvent *eventp) { const XReparentEvent *e = (const XReparentEvent *) eventp; fprintf(stderr, " event 0x%lx, window 0x%lx, parent 0x%lx,\n", e->event, e->window, e->parent); fprintf(stderr, " (%d,%d), override %s\n", e->x, e->y, e->override_redirect ? Yes : No); return; } static void do_ConfigureNotify (const XEvent *eventp) { const XConfigureEvent *e = (const XConfigureEvent *) eventp; fprintf(stderr, " event 0x%lx, window 0x%lx, (%d,%d), width %d, height %d,\n", e->event, e->window, e->x, e->y, e->width, e->height); fprintf(stderr, " border_width %d, above 0x%lx, override %s\n", e->border_width, e->above, e->override_redirect ? Yes : No); return; } static void do_ConfigureRequest (const XEvent *eventp) { const XConfigureRequestEvent *e = (const XConfigureRequestEvent *) eventp; char *detail; char ddummy[10]; switch (e->detail) { case Above: detail = "Above"; break; case Below: detail = "Below"; break; case TopIf: detail = "TopIf"; break; case BottomIf: detail = "BottomIf"; break; case Opposite: detail = "Opposite"; break; default: detail = ddummy; sprintf (ddummy, "%d", e->detail); break; } fprintf(stderr, " parent 0x%lx, window 0x%lx, (%d,%d), width %d, height %d,\n", e->parent, e->window, e->x, e->y, e->width, e->height); fprintf(stderr, " border_width %d, above 0x%lx, detail %s, value 0x%lx\n", e->border_width, e->above, detail, e->value_mask); return; } static void do_GravityNotify (const XEvent *eventp) { const XGravityEvent *e = (const XGravityEvent *) eventp; fprintf(stderr, " event 0x%lx, window 0x%lx, (%d,%d)\n", e->event, e->window, e->x, e->y); return; } static void do_ResizeRequest (const XEvent *eventp) { const XResizeRequestEvent *e = (const XResizeRequestEvent *) eventp; fprintf(stderr, " width %d, height %d\n", e->width, e->height); return; } static void do_CirculateNotify (const XEvent *eventp) { const XCirculateEvent *e = (const XCirculateEvent *) eventp; char *p; char pdummy[10]; switch (e->place) { case PlaceOnTop: p = "PlaceOnTop"; break; case PlaceOnBottom: p = "PlaceOnBottom"; break; default: p = pdummy; sprintf (pdummy, "%d", e->place); break; } fprintf(stderr, " event 0x%lx, window 0x%lx, place %s\n", e->event, e->window, p); return; } static void do_CirculateRequest (const XEvent *eventp) { const XCirculateRequestEvent *e = (const XCirculateRequestEvent *) eventp; char *p; char pdummy[10]; switch (e->place) { case PlaceOnTop: p = "PlaceOnTop"; break; case PlaceOnBottom: p = "PlaceOnBottom"; break; default: p = pdummy; sprintf (pdummy, "%d", e->place); break; } fprintf(stderr, " parent 0x%lx, window 0x%lx, place %s\n", e->parent, e->window, p); return; } static void do_PropertyNotify (const XEvent *eventp) { const XPropertyEvent *e = (const XPropertyEvent *) eventp; char *aname = XGetAtomName (display, e->atom); char *s; char sdummy[10]; switch (e->state) { case PropertyNewValue: s = "PropertyNewValue"; break; case PropertyDelete: s = "PropertyDelete"; break; default: s = sdummy; sprintf (sdummy, "%d", e->state); break; } fprintf(stderr, " atom 0x%lx (%s), time %lu, state %s\n", e->atom, aname ? aname : Unknown, e->time, s); if (aname) XFree (aname); return; } static void do_SelectionClear (const XEvent *eventp) { const XSelectionClearEvent *e = (const XSelectionClearEvent *) eventp; char *sname = XGetAtomName (display, e->selection); fprintf(stderr, " selection 0x%lx (%s), time %lu\n", e->selection, sname ? sname : Unknown, e->time); if (sname) XFree (sname); return; } static void do_SelectionRequest (const XEvent *eventp) { const XSelectionRequestEvent *e = (const XSelectionRequestEvent *) eventp; char *sname = XGetAtomName (display, e->selection); char *tname = XGetAtomName (display, e->target); char *pname = XGetAtomName (display, e->property); fprintf(stderr, " owner 0x%lx, requestor 0x%lx, selection 0x%lx (%s),\n", e->owner, e->requestor, e->selection, sname ? sname : Unknown); fprintf(stderr, " target 0x%lx (%s), property 0x%lx (%s), time %lu\n", e->target, tname ? tname : Unknown, e->property, pname ? pname : Unknown, e->time); if (sname) XFree (sname); if (tname) XFree (tname); if (pname) XFree (pname); return; } static void do_SelectionNotify (const XEvent *eventp) { const XSelectionEvent *e = (const XSelectionEvent *) eventp; char *sname = XGetAtomName (display, e->selection); char *tname = XGetAtomName (display, e->target); char *pname = XGetAtomName (display, e->property); fprintf(stderr, " selection 0x%lx (%s), target 0x%lx (%s),\n", e->selection, sname ? sname : Unknown, e->target, tname ? tname : Unknown); fprintf(stderr, " property 0x%lx (%s), time %lu\n", e->property, pname ? pname : Unknown, e->time); if (sname) XFree (sname); if (tname) XFree (tname); if (pname) XFree (pname); return; } static void do_ColormapNotify (const XEvent *eventp) { const XColormapEvent *e = (const XColormapEvent *) eventp; char *s; char sdummy[10]; switch (e->state) { case ColormapInstalled: s = "ColormapInstalled"; break; case ColormapUninstalled: s = "ColormapUninstalled"; break; default: s = sdummy; sprintf (sdummy, "%d", e->state); break; } fprintf(stderr, " colormap 0x%lx, new %s, state %s\n", e->colormap, e->new ? Yes : No, s); return; } static void do_ClientMessage (const XEvent *eventp) { const XClientMessageEvent *e = (const XClientMessageEvent *) eventp; char *mname = XGetAtomName (display, e->message_type); fprintf(stderr, " message_type 0x%lx (%s), format %d\n", e->message_type, mname ? mname : Unknown, e->format); if (mname) XFree (mname); return; } static void do_MappingNotify (const XEvent *eventp) { const XMappingEvent *e = (const XMappingEvent *) eventp; char *r; char rdummy[10]; switch (e->request) { case MappingModifier: r = "MappingModifier"; break; case MappingKeyboard: r = "MappingKeyboard"; break; case MappingPointer: r = "MappingPointer"; break; default: r = rdummy; sprintf (rdummy, "%d", e->request); break; } fprintf(stderr, " request %s, first_keycode %d, count %d\n", r, e->first_keycode, e->count); XRefreshKeyboardMapping((XMappingEvent *)e); return; } void pxPrintEvent(const XEvent *event) { switch (event->type) { case KeyPress: prologue (event, "KeyPress"); do_KeyPress (event); break; case KeyRelease: prologue (event, "KeyRelease"); do_KeyRelease (event); break; case ButtonPress: prologue (event, "ButtonPress"); do_ButtonPress (event); break; case ButtonRelease: prologue (event, "ButtonRelease"); do_ButtonRelease (event); break; case MotionNotify: prologue (event, "MotionNotify"); do_MotionNotify (event); break; case EnterNotify: prologue (event, "EnterNotify"); do_EnterNotify (event); break; case LeaveNotify: prologue (event, "LeaveNotify"); do_LeaveNotify (event); break; case FocusIn: prologue (event, "FocusIn"); do_FocusIn (event); break; case FocusOut: prologue (event, "FocusOut"); do_FocusOut (event); break; case KeymapNotify: prologue (event, "KeymapNotify"); do_KeymapNotify (event); break; case Expose: prologue (event, "Expose"); do_Expose (event); break; case GraphicsExpose: prologue (event, "GraphicsExpose"); do_GraphicsExpose (event); break; case NoExpose: prologue (event, "NoExpose"); do_NoExpose (event); break; case VisibilityNotify: prologue (event, "VisibilityNotify"); do_VisibilityNotify (event); break; case CreateNotify: prologue (event, "CreateNotify"); do_CreateNotify (event); break; case DestroyNotify: prologue (event, "DestroyNotify"); do_DestroyNotify (event); break; case UnmapNotify: prologue (event, "UnmapNotify"); do_UnmapNotify (event); break; case MapNotify: prologue (event, "MapNotify"); do_MapNotify (event); break; case MapRequest: prologue (event, "MapRequest"); do_MapRequest (event); break; case ReparentNotify: prologue (event, "ReparentNotify"); do_ReparentNotify (event); break; case ConfigureNotify: prologue (event, "ConfigureNotify"); do_ConfigureNotify (event); break; case ConfigureRequest: prologue (event, "ConfigureRequest"); do_ConfigureRequest (event); break; case GravityNotify: prologue (event, "GravityNotify"); do_GravityNotify (event); break; case ResizeRequest: prologue (event, "ResizeRequest"); do_ResizeRequest (event); break; case CirculateNotify: prologue (event, "CirculateNotify"); do_CirculateNotify (event); break; case CirculateRequest: prologue (event, "CirculateRequest"); do_CirculateRequest (event); break; case PropertyNotify: prologue (event, "PropertyNotify"); do_PropertyNotify (event); break; case SelectionClear: prologue (event, "SelectionClear"); do_SelectionClear (event); break; case SelectionRequest: prologue (event, "SelectionRequest"); do_SelectionRequest (event); break; case SelectionNotify: prologue (event, "SelectionNotify"); do_SelectionNotify (event); break; case ColormapNotify: prologue (event, "ColormapNotify"); do_ColormapNotify (event); break; case ClientMessage: prologue (event, "ClientMessage"); do_ClientMessage (event); break; case MappingNotify: prologue (event, "MappingNotify"); do_MappingNotify (event); break; default: fprintf(stderr, "Unknown event type %d\n", event->type); break; } } void move_callback(Widget parent, XtPointer w, XEvent *ev, Boolean *flag) { fprintf(stderr, "mouse move\n") ; } void menu_callback(Widget parent, XtPointer w, XEvent *ev, Boolean *flag) { XButtonEvent *event = (XButtonEvent *)ev ; fprintf(stderr, "button press\n") ; XmMenuPosition(popup_menu, event) ; XtManageChild(popup_menu) ; } main (int argc, char *argv[]) { XmString line, square, circle, exit, exit_acc; Widget toplevel, main_w, drawing_a; void popup_cb(Widget, XtPointer, XtPointer); XtAppContext app; Arg args[4]; int n; XtSetLanguageProc (NULL, NULL, NULL); toplevel = XtVaOpenApplication (&app, "Demos", NULL, 0, &argc, argv, NULL, sessionShellWidgetClass, NULL); display = XtDisplay(toplevel); /* Create a MainWindow widget that contains a DrawingArea in ** its work window. */ n = 0; XtSetArg (args[n], XmNscrollingPolicy, XmAUTOMATIC); n++; main_w = XmCreateMainWindow (toplevel, "main_w", args, n); /* Create a DrawingArea -- no actual drawing will be done. */ n = 0; XtSetArg (args[n], XmNwidth, 500); n++; XtSetArg (args[n], XmNheight, 500); n++; drawing_a = XmCreateDrawingArea (main_w, "drawing_a", args, n); XtManageChild (drawing_a); line = XmStringCreateLocalized ("Line"); square = XmStringCreateLocalized ("Square"); circle = XmStringCreateLocalized ("Circle"); exit = XmStringCreateLocalized ("Exit"); exit_acc = XmStringCreateLocalized ("Ctrl+C"); popup_menu = XmVaCreateSimplePopupMenu (drawing_a, "popup", popup_cb, XmVaPUSHBUTTON, line, 'L', NULL, NULL, XmVaPUSHBUTTON, square, 'S', NULL, NULL, XmVaPUSHBUTTON, circle, 'C', NULL, NULL, XmVaSEPARATOR, XmVaPUSHBUTTON, exit, 'x', "Ctrlc", exit_acc, NULL); XmStringFree (line); XmStringFree (square); XmStringFree (circle); XmStringFree (exit); XmStringFree (exit_acc); XtAddEventHandler(drawing_a, ButtonPressMask, False, menu_callback, NULL) ; XtAddEventHandler(drawing_a, ButtonMotionMask, False, move_callback, NULL) ; XtManageChild (main_w); XtRealizeWidget (toplevel); /* XtAppMainLoop (app); */ do { XEvent event ; XtAppNextEvent(app, &event) ; pxPrintEvent(&event) ; XtDispatchEvent(&event) ; } while (1) ; } /* popup_cb() -- invoked when the user selects an item in the popup menu */ void popup_cb (Widget menu_item, XtPointer client_data, XtPointer call_data) { int item_no = (int) client_data; if (item_no == 3) /* Exit was selected -- exit */ exit (0); /* Otherwise, just print the selection */ puts (XtName (menu_item)); }