Path: utzoo!attcan!utgpu!utstat!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!ucbvax!hplabs!hplabsz!mayer From: mayer@hplabsz.HPL.HP.COM (Niels Mayer) Newsgroups: comp.windows.x,hp.windows.motif Subject: Re: Need help in interactive selection of a motif widget/gadget Message-ID: <4228@hplabsz.HPL.HP.COM> Date: 27 Oct 89 08:53:13 GMT References: <4219@hplabsz.HPL.HP.COM> Reply-To: mayer@hplabs.hp.com (Niels Mayer) Organization: Hewlett-Packard Labs, Software Technology Lab, Palo Alto, CA. Lines: 92 Summary: Expires: Sender: Followup-To: In article <4219@hplabsz.HPL.HP.COM> mayer@hplabs.hp.com (Niels Mayer) writes: >I have added a primitive to my WINTERP application (a Motif application >prototyping/develpment/delivery environment) which will allow users click >on a widget to get back the WIDGET-OBJECT corresponding to the widget. > ... [description of bug deleted] ... >Am I doing something wrong? Is this a Motif or Xtoolkit bug? Do I have to >add yet another special kludge for a gadget-inside-a-manager- >-inside-a-scrolled-window? Inquiring minds want to know. Please ignore my previous request. When I wrote my GET_MOUSED_WIDGET routine, I misunderstood how XTranslateCoordinates() worked. After rereading the manpage, I was able to find the (trivial) bug in my code. Clearly a case of earthquake-induced braindamage on my part. Here's the working version of GET_MOUSED_WIDGET. You may find it useful... /****************************************************************************** * (GET_MOUSED_WIDGET) * evaluating this function will change the cursor to a crossbar, indicating * that the user is to 'click' the mouse to designate an object on the screen. * If the user clicks on a visual item within WINTERP, this fucntion will * return the WIDGETOBJ associated with the visual item. ******************************************************************************/ LVAL Wut_UserClick_To_WidgetObj() { extern Display* display; /* global in winterp.c */ extern LVAL Wcls_WidgetID_To_WidgetObj(); /* from w_classes.c */ extern XmGadget _XmInputInGadget(); /* in Xm/GadetUtils.c extern'd in XmP.h */ Cursor cursor = XCreateFontCursor(display, XC_crosshair); Window root = DefaultRootWindow(display); Window parent_win, cur_win, child_win; int win_x, win_y; Widget widget_id, gadget_id; XEvent event; Bool xtc_ok; xllastarg(); if (GrabSuccess != XGrabPointer(display, root, 0, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, cursor, CurrentTime)) xlfail("GET_MOUSED_WIDGET -- couldn't grab pointer (XGrabPointer() failed)."); XWindowEvent(display, root, ButtonPressMask, &event); XUngrabPointer(display, CurrentTime); XFlush(display); if (event.type != ButtonPress) /* sanity check: ensure valid access to event.xbutton variant */ xlfail("Bug in GET_MOUSED_WIDGET -- expected a button event."); if (!event.xbutton.subwindow) xlfail("GET_MOUSED_WIDGET aborted -- you clicked on the root window."); parent_win = event.xbutton.window; /* ASSERT event.xbutton.window == root, due to using XWindowEvent(root) */ win_x = event.xbutton.x; win_y = event.xbutton.y; cur_win = event.xbutton.subwindow; while ((xtc_ok = XTranslateCoordinates(display, parent_win, cur_win, win_x, win_y, /* give the x,y coords of event in parent_w */ &win_x, &win_y, /* return the x,y coords relative to cur_win */ &child_win)) /* returns child window of cur_win if that contains coords, else nil */ && child_win) { #ifdef DEBUG_WINTERP_1 fprintf(stderr, "parent_win=%lx, cur_win=%lx, child_win=%lx\n", parent_win, cur_win, child_win); #endif parent_win = cur_win; cur_win = child_win; } #ifdef DEBUG_WINTERP_1 fprintf(stderr, " Smallest window containing userclick is %lx\n", cur_win); #endif if (!xtc_ok) xlerror("Bug in GET_MOUSED_WIDGET -- XTranslateCoordinates() failed."); if (!(widget_id = XtWindowToWidget(display, cur_win))) xlfail("GET_MOUSED_WIDGET -- Couldn't find widget associated with window.\n (Is the selected widget/window inside a different application?).\n"); /* if the widget is a composite it may be managing a gadget -- attempt to retrieve it by looking up x,y coords in manager */ if (XtIsComposite(widget_id) && (gadget_id = (Widget) _XmInputInGadget(widget_id, win_x, win_y))) return (Wcls_WidgetID_To_WidgetObj(gadget_id)); /* then return the WIDGETOBJ assoc'd with gadget */ else return (Wcls_WidgetID_To_WidgetObj(widget_id)); /* otherwise, we return the WIDGETOBJ assoc'd with smallest window */ } ------------------------------------------------------------------------------- Niels Mayer -- hplabs!mayer -- mayer@hplabs.hp.com Human-Computer Interaction Department Hewlett-Packard Laboratories Palo Alto, CA. *