+ if (m_drawingArea)
+ return m_drawingArea;
+ else
+ return m_mainWidget;
+}
+
+WXWidget wxWindow::GetClientWidget() const
+{
+ if (m_drawingArea != (WXWidget) 0)
+ return m_drawingArea;
+ else
+ return GetMainWidget();
+}
+
+WXWidget wxWindow::GetTopWidget() const
+{
+ return GetMainWidget();
+}
+
+void wxCanvasRepaintProc (Widget drawingArea, XtPointer clientData,
+ XmDrawingAreaCallbackStruct * cbs)
+{
+ if (!wxWidgetHashTable->Get ((long) (Widget) drawingArea))
+ return;
+
+ XEvent * event = cbs->event;
+ wxWindow * win = (wxWindow *) clientData;
+ Display * display = (Display *) win->GetXDisplay();
+
+ switch (event->type)
+ {
+ case Expose:
+ {
+ wxRect* rect = new wxRect(event->xexpose.x, event->xexpose.y,
+ event->xexpose.width, event->xexpose.height);
+ /*
+ cout << "Expose proc. wxRect: " << rect->x << ", " << rect->y << ", ";
+ cout << rect->width << ", " << rect->height << "\n\n";
+ */
+
+ win->m_updateRects.Append((wxObject*) rect);
+
+ if (event -> xexpose.count == 0)
+ {
+ wxPaintEvent event(win->GetId());
+ event.SetEventObject(win);
+ win->GetEventHandler()->ProcessEvent(event);
+
+ win->ClearUpdateRects();
+ }
+ break;
+ }
+ default:
+ {
+ cout << "\n\nNew Event ! is = " << event -> type << "\n";
+ break;
+ }
+ }
+}
+
+// Unable to deal with Enter/Leave without a separate EventHandler (Motif 1.1.4)
+void
+wxCanvasEnterLeave (Widget drawingArea, XtPointer clientData, XCrossingEvent * event)
+{
+ XmDrawingAreaCallbackStruct cbs;
+ XEvent ev;
+
+ //if (event->mode!=NotifyNormal)
+ // return ;
+
+// ev = *((XEvent *) event); // Causes Purify error (copying too many bytes)
+ ((XCrossingEvent &) ev) = *event;
+
+ cbs.reason = XmCR_INPUT;
+ cbs.event = &ev;
+
+ wxCanvasInputEvent (drawingArea, (XtPointer) NULL, &cbs);
+}
+
+// Fix to make it work under Motif 1.0 (!)
+void wxCanvasMotionEvent (Widget drawingArea, XButtonEvent * event)
+{
+#if XmVersion<=1000
+
+ XmDrawingAreaCallbackStruct cbs;
+ XEvent ev;
+
+ //ev.xbutton = *event;
+ ev = *((XEvent *) event);
+ cbs.reason = XmCR_INPUT;
+ cbs.event = &ev;
+
+ wxCanvasInputEvent (drawingArea, (XtPointer) NULL, &cbs);
+#endif
+}
+
+void wxCanvasInputEvent (Widget drawingArea, XtPointer data, XmDrawingAreaCallbackStruct * cbs)
+{
+ wxWindow *canvas = (wxWindow *) wxWidgetHashTable->Get ((long) (Widget) drawingArea);
+ XEvent local_event;
+
+ if (canvas==NULL)
+ return ;
+
+ if (cbs->reason != XmCR_INPUT)
+ return;
+
+ local_event = *(cbs->event); // We must keep a copy!
+
+ /*
+ switch (local_event.xany.type)
+ {
+ case EnterNotify:
+ cout << "EnterNotify\n";
+ break;
+ case LeaveNotify:
+ cout << "LeaveNotify\n";
+ break;
+ case ButtonPress:
+ cout << "ButtonPress\n";
+ break;
+ case ButtonRelease:
+ cout << "ButtonRelease\n";
+ break;
+ case MotionNotify:
+ cout << "MotionNotify\n";
+ break;
+ default:
+ cout << "Something else\n";
+ break;
+ }
+ */
+
+ switch (local_event.xany.type)
+ {
+ case EnterNotify:
+ case LeaveNotify:
+ case ButtonPress:
+ case ButtonRelease:
+ case MotionNotify:
+ {
+ wxEventType eventType = wxEVT_NULL;
+
+ if (local_event.xany.type == EnterNotify)
+ {
+ //if (local_event.xcrossing.mode!=NotifyNormal)
+ // return ; // Ignore grab events
+ eventType = wxEVT_ENTER_WINDOW;
+// canvas->GetEventHandler()->OnSetFocus();
+ }
+ else if (local_event.xany.type == LeaveNotify)
+ {
+ //if (local_event.xcrossing.mode!=NotifyNormal)
+ // return ; // Ignore grab events
+ eventType = wxEVT_LEAVE_WINDOW;
+// canvas->GetEventHandler()->OnKillFocus();
+ }
+ else if (local_event.xany.type == MotionNotify)
+ {
+ eventType = wxEVT_MOTION;
+ if (local_event.xmotion.is_hint == NotifyHint)
+ {
+ Window root, child;
+ Display *dpy = XtDisplay (drawingArea);
+
+ XQueryPointer (dpy, XtWindow (drawingArea),
+ &root, &child,
+ &local_event.xmotion.x_root,
+ &local_event.xmotion.y_root,
+ &local_event.xmotion.x,
+ &local_event.xmotion.y,
+ &local_event.xmotion.state);
+ }
+ else
+ {
+ }
+ }
+
+ else if (local_event.xany.type == ButtonPress)
+ {
+ if (local_event.xbutton.button == Button1)
+ {
+ eventType = wxEVT_LEFT_DOWN;
+ canvas->m_button1Pressed = TRUE;
+ }
+ else if (local_event.xbutton.button == Button2)
+ {
+ eventType = wxEVT_MIDDLE_DOWN;
+ canvas->m_button2Pressed = TRUE;
+ }
+ else if (local_event.xbutton.button == Button3)
+ {
+ eventType = wxEVT_RIGHT_DOWN;
+ canvas->m_button3Pressed = TRUE;
+ }
+ }
+ else if (local_event.xany.type == ButtonRelease)
+ {
+ if (local_event.xbutton.button == Button1)
+ {
+ eventType = wxEVT_LEFT_UP;
+ canvas->m_button1Pressed = FALSE;
+ }
+ else if (local_event.xbutton.button == Button2)
+ {
+ eventType = wxEVT_MIDDLE_UP;
+ canvas->m_button2Pressed = FALSE;
+ }
+ else if (local_event.xbutton.button == Button3)
+ {
+ eventType = wxEVT_RIGHT_UP;
+ canvas->m_button3Pressed = FALSE;
+ }
+ }
+
+ wxMouseEvent wxevent (eventType);
+ wxevent.m_eventHandle = (char *) &local_event;
+
+ wxevent.m_leftDown = ((eventType == wxEVT_LEFT_DOWN)
+ || (event_left_is_down (&local_event)
+ && (eventType != wxEVT_LEFT_UP)));
+ wxevent.m_middleDown = ((eventType == wxEVT_MIDDLE_DOWN)
+ || (event_middle_is_down (&local_event)
+ && (eventType != wxEVT_MIDDLE_UP)));
+ wxevent.m_rightDown = ((eventType == wxEVT_RIGHT_DOWN)
+ || (event_right_is_down (&local_event)
+ && (eventType != wxEVT_RIGHT_UP)));
+
+ wxevent.m_shiftDown = local_event.xbutton.state & ShiftMask;
+ wxevent.m_controlDown = local_event.xbutton.state & ControlMask;
+ wxevent.m_altDown = local_event.xbutton.state & Mod3Mask;
+ wxevent.m_metaDown = local_event.xbutton.state & Mod1Mask;
+ wxevent.SetTimestamp(local_event.xbutton.time);
+
+ // Now check if we need to translate this event into a double click
+ if (TRUE) // canvas->doubleClickAllowed)
+ {
+ if (wxevent.ButtonDown())
+ {
+ long dclickTime = XtGetMultiClickTime((Display*) wxGetDisplay()) ;
+
+ // get button and time-stamp
+ int button = 0;
+ if (wxevent.LeftDown()) button = 1;
+ else if (wxevent.MiddleDown()) button = 2;
+ else if (wxevent.RightDown()) button = 3;
+ long ts = wxevent.GetTimestamp();
+ // check, if single or double click
+ if (canvas->m_lastButton && canvas->m_lastButton==button && (ts - canvas->m_lastTS) < dclickTime)
+ {
+ // I have a dclick
+ canvas->m_lastButton = 0;
+ switch ( eventType )
+ {
+ case wxEVT_LEFT_DOWN:
+ wxevent.SetEventType(wxEVT_LEFT_DCLICK);
+ break;
+ case wxEVT_MIDDLE_DOWN:
+ wxevent.SetEventType(wxEVT_MIDDLE_DCLICK);
+ break;
+ case wxEVT_RIGHT_DOWN:
+ wxevent.SetEventType(wxEVT_RIGHT_DCLICK);
+ break;
+
+ default :
+ break;
+ }
+
+ }
+ else
+ {
+ // not fast enough or different button
+ canvas->m_lastTS = ts;
+ canvas->m_lastButton = button;
+ }
+ }
+ }
+
+ wxevent.SetId(canvas->GetId());
+ wxevent.SetEventObject(canvas);
+ wxevent.m_x = local_event.xbutton.x;
+ wxevent.m_y = local_event.xbutton.y;
+ canvas->GetEventHandler()->ProcessEvent (wxevent);
+ /*
+ if (eventType == wxEVT_ENTER_WINDOW ||
+ eventType == wxEVT_LEAVE_WINDOW ||
+ eventType == wxEVT_MOTION
+ )
+ return;
+ */
+ break;
+ }
+ case KeyPress:
+ {
+ KeySym keySym;
+// XComposeStatus compose;
+// (void) XLookupString ((XKeyEvent *) & local_event, wxBuffer, 20, &keySym, &compose);
+ (void) XLookupString ((XKeyEvent *) & local_event, wxBuffer, 20, &keySym, NULL);
+ int id = wxCharCodeXToWX (keySym);
+
+ wxKeyEvent event (wxEVT_CHAR);
+
+ if (local_event.xkey.state & ShiftMask)
+ event.m_shiftDown = TRUE;
+ if (local_event.xkey.state & ControlMask)
+ event.m_controlDown = TRUE;
+ if (local_event.xkey.state & Mod3Mask)
+ event.m_altDown = TRUE;
+ if (local_event.xkey.state & Mod1Mask)
+ event.m_metaDown = TRUE;
+ event.SetEventObject(canvas);
+ event.m_keyCode = id;
+ event.SetTimestamp(local_event.xkey.time);
+
+ if (id > -1)
+ {
+ // Implement wxFrame::OnCharHook by checking ancestor.
+ wxWindow *parent = canvas->GetParent();
+ while (parent && !parent->IsKindOf(CLASSINFO(wxFrame)))
+ parent = parent->GetParent();
+
+ if (parent)
+ {
+ event.SetEventType(wxEVT_CHAR_HOOK);
+ if (parent->GetEventHandler()->ProcessEvent(event))
+ return;
+ event.SetEventType(wxEVT_CHAR);
+ }
+
+ canvas->GetEventHandler()->ProcessEvent (event);
+ }
+ break;
+ }
+ case FocusIn:
+ {
+ if (local_event.xfocus.detail != NotifyPointer)
+ {
+ wxFocusEvent event(wxEVT_SET_FOCUS, canvas->GetId());
+ event.SetEventObject(canvas);
+ canvas->GetEventHandler()->ProcessEvent(event);
+ }
+ break;
+ }
+ case FocusOut:
+ {
+ if (local_event.xfocus.detail != NotifyPointer)
+ {
+ wxFocusEvent event(wxEVT_KILL_FOCUS, canvas->GetId());
+ event.SetEventObject(canvas);
+ canvas->GetEventHandler()->ProcessEvent(event);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+void wxWindow::DoPaint()
+{
+ //TODO : make a temporary gc so we can do the XCopyArea below
+ if (0) // m_backingPixmap)
+ {
+ /*
+ Widget drawingArea = (Widget) m_drawingArea;
+ // int orig = GetDC()->GetLogicalFunction();
+ // GetDC()->SetLogicalFunction (wxCOPY);
+
+ // TODO: it may not be necessary to store m_pixmapOffsetX/Y; we
+ // should be able to calculate them.
+ XCopyArea (XtDisplay (drawingArea), m_backingPixmap, XtWindow (drawingArea), GetDC ()->gc,
+ m_pixmapOffsetX, m_pixmapOffsetY,
+ m_pixmapWidth, m_pixmapHeight,
+ 0, 0);
+
+ // GetDC()->SetLogicalFunction (orig);
+ */
+ }
+ else
+ {
+ wxPaintEvent event(GetId());
+ event.SetEventObject(this);
+ GetEventHandler()->ProcessEvent(event);
+ }
+}
+
+// SetSize, but as per old wxCanvas (with drawing widget etc.)
+void wxWindow::CanvasSetSize (int x, int y, int w, int h, int sizeFlags)
+{
+ // A bit of optimization to help sort out the flickers.
+ int oldX, oldY, oldW, oldH;
+ GetSize(& oldW, & oldH);
+ GetPosition(& oldX, & oldY);
+
+ bool useOldPos = FALSE;
+ bool useOldSize = FALSE;
+
+ if ((x == -1) && (x == -1) && ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0))
+ useOldPos = TRUE;
+ else if (x == oldX && y == oldY)
+ useOldPos = TRUE;
+
+ if ((w == -1) && (h == -1))
+ useOldSize = TRUE;
+ else if (w == oldW && h == oldH)
+ useOldSize = TRUE;
+
+ if (useOldPos && useOldSize)
+ return;
+
+ Widget drawingArea = (Widget) m_drawingArea;
+ bool managed = XtIsManaged(m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow);
+
+ if (managed)
+ XtUnmanageChild (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow);
+ XtVaSetValues((Widget) m_drawingArea, XmNresizePolicy, XmRESIZE_ANY, NULL);
+
+ int xx = x; int yy = y;
+ AdjustForParentClientOrigin(xx, yy, sizeFlags);
+
+ if (!useOldPos)
+ {
+ if (x > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
+ {
+ XtVaSetValues (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow,
+ XmNx, xx, NULL);
+ }
+
+ if (y > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
+ {
+ XtVaSetValues (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow,
+ XmNy, yy, NULL);
+ }
+ }
+
+ if (!useOldSize)
+ {
+
+ if (w > -1)
+ {
+ if (m_borderWidget)
+ {
+ XtVaSetValues ((Widget) m_borderWidget, XmNwidth, w, NULL);
+ short thick, margin;
+ XtVaGetValues ((Widget) m_borderWidget,
+ XmNshadowThickness, &thick,
+ XmNmarginWidth, &margin,
+ NULL);
+ w -= 2 * (thick + margin);
+ }
+
+ XtVaSetValues ((Widget) m_scrolledWindow, XmNwidth, w, NULL);
+
+ Dimension spacing;
+ Widget sbar;
+ XtVaGetValues ((Widget) m_scrolledWindow,
+ XmNspacing, &spacing,
+ XmNverticalScrollBar, &sbar,
+ NULL);
+ Dimension wsbar;
+ if (sbar)
+ XtVaGetValues (sbar, XmNwidth, &wsbar, NULL);
+ else
+ wsbar = 0;
+
+ w -= (spacing + wsbar);
+
+ XtVaSetValues ((Widget) m_drawingArea, XmNwidth, w, NULL);
+ }
+ if (h > -1)
+ {
+ if (m_borderWidget)
+ {
+ XtVaSetValues ((Widget) m_borderWidget, XmNheight, h, NULL);
+ short thick, margin;
+ XtVaGetValues ((Widget) m_borderWidget,
+ XmNshadowThickness, &thick,
+ XmNmarginHeight, &margin,
+ NULL);
+ h -= 2 * (thick + margin);
+ }
+
+ XtVaSetValues ((Widget) m_scrolledWindow, XmNheight, h, NULL);
+
+ Dimension spacing;
+ Widget sbar;
+ XtVaGetValues ((Widget) m_scrolledWindow,
+ XmNspacing, &spacing,
+ XmNhorizontalScrollBar, &sbar,
+ NULL);
+ Dimension wsbar;
+ if (sbar)
+ XtVaGetValues (sbar, XmNheight, &wsbar, NULL);
+ else
+ wsbar = 0;
+
+ h -= (spacing + wsbar);
+
+ XtVaSetValues ((Widget) m_drawingArea, XmNheight, h, NULL);
+ }
+ }
+
+ if (managed)
+ XtManageChild (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow);
+ XtVaSetValues((Widget) m_drawingArea, XmNresizePolicy, XmRESIZE_NONE, NULL);
+
+ /*
+ int ww, hh;
+ GetClientSize (&ww, &hh);
+ wxSizeEvent sizeEvent(wxSize(ww, hh), GetId());
+ sizeEvent.SetEventObject(this);
+
+ GetEventHandler()->ProcessEvent(sizeEvent);
+ */
+
+}
+
+void wxWindow::CanvasSetClientSize (int w, int h)
+{
+ Widget drawingArea = (Widget) m_drawingArea;
+
+ XtVaSetValues((Widget) m_drawingArea, XmNresizePolicy, XmRESIZE_ANY, NULL);
+
+ if (w > -1)
+ XtVaSetValues ((Widget) m_drawingArea, XmNwidth, w, NULL);
+ if (h > -1)
+ XtVaSetValues ((Widget) m_drawingArea, XmNheight, h, NULL);
+ /* TODO: is this necessary?
+ allowRepainting = FALSE;
+
+ XSync (XtDisplay (drawingArea), FALSE);
+ XEvent event;
+ while (XtAppPending (wxTheApp->appContext))
+ {
+ XFlush (XtDisplay (drawingArea));
+ XtAppNextEvent (wxTheApp->appContext, &event);
+ XtDispatchEvent (&event);
+ }
+ */
+
+ XtVaSetValues((Widget) m_drawingArea, XmNresizePolicy, XmRESIZE_NONE, NULL);
+
+ /* TODO
+ allowRepainting = TRUE;
+ DoRefresh ();
+ */
+
+ /*
+ wxSizeEvent sizeEvent(wxSize(w, h), GetId());
+ sizeEvent.SetEventObject(this);
+
+ GetEventHandler()->ProcessEvent(sizeEvent);
+ */
+}
+
+void wxWindow::CanvasGetClientSize (int *w, int *h) const
+{
+ // Must return the same thing that was set via SetClientSize
+ Dimension xx, yy;
+ XtVaGetValues ((Widget) m_drawingArea, XmNwidth, &xx, XmNheight, &yy, NULL);
+ *w = xx;
+ *h = yy;
+}
+
+void wxWindow::CanvasGetSize (int *w, int *h) const
+{
+ Dimension xx, yy;
+ if ((Widget) m_borderWidget)
+ XtVaGetValues ((Widget) m_borderWidget, XmNwidth, &xx, XmNheight, &yy, NULL);
+ else if ((Widget) m_scrolledWindow)
+ XtVaGetValues ((Widget) m_scrolledWindow, XmNwidth, &xx, XmNheight, &yy, NULL);
+ else
+ XtVaGetValues ((Widget) m_drawingArea, XmNwidth, &xx, XmNheight, &yy, NULL);
+
+ *w = xx;
+ *h = yy;
+}
+
+void wxWindow::CanvasGetPosition (int *x, int *y) const
+{
+ Position xx, yy;
+ XtVaGetValues (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow, XmNx, &xx, XmNy, &yy, NULL);
+
+ // We may be faking the client origin.
+ // So a window that's really at (0, 30) may appear
+ // (to wxWin apps) to be at (0, 0).
+ if (GetParent())
+ {
+ wxPoint pt(GetParent()->GetClientAreaOrigin());
+ xx -= pt.x;
+ yy -= pt.y;
+ }
+
+ *x = xx;
+ *y = yy;
+}
+
+// Add to hash table, add event handler
+bool wxWindow::AttachWidget (wxWindow* parent, WXWidget mainWidget,
+ WXWidget formWidget, int x, int y, int width, int height)
+{
+ wxAddWindowToTable((Widget) mainWidget, this);
+ if (CanAddEventHandler())
+ {
+ XtAddEventHandler((Widget) mainWidget,
+ ButtonPressMask | ButtonReleaseMask | PointerMotionMask, // | KeyPressMask,
+ False,
+ wxPanelItemEventHandler,
+ (XtPointer) this);
+ }
+
+ if (!formWidget)
+ {
+ XtTranslations ptr;
+ XtOverrideTranslations ((Widget) mainWidget,
+ ptr = XtParseTranslationTable ("<Configure>: resize()"));
+ XtFree ((char *) ptr);
+ }
+
+ // Some widgets have a parent form widget, e.g. wxRadioBox
+ if (formWidget)
+ {
+ if (!wxAddWindowToTable((Widget) formWidget, this))
+ return FALSE;
+
+ XtTranslations ptr;
+ XtOverrideTranslations ((Widget) formWidget,
+ ptr = XtParseTranslationTable ("<Configure>: resize()"));
+ XtFree ((char *) ptr);
+ }
+
+ if (x == -1)
+ x = 0;
+ if (y == -1)
+ y = 0;
+ SetSize (x, y, width, height);
+
+ return TRUE;
+}
+
+// Remove event handler, remove from hash table
+bool wxWindow::DetachWidget(WXWidget widget)
+{
+ if (CanAddEventHandler())
+ {
+ XtRemoveEventHandler((Widget) widget,
+ ButtonPressMask | ButtonReleaseMask | PointerMotionMask, // | KeyPressMask,
+ False,
+ wxPanelItemEventHandler,
+ (XtPointer)this);
+ }
+
+ wxDeleteWindowFromTable((Widget) widget);
+ return TRUE;
+}
+
+void wxPanelItemEventHandler (Widget wid,
+ XtPointer client_data,
+ XEvent* event,
+ Boolean *continueToDispatch)
+{
+ // Widget can be a label or the actual widget.
+
+ wxWindow *window = (wxWindow *)wxWidgetHashTable->Get((long)wid);
+ if (window)
+ {
+ wxMouseEvent wxevent(0);
+ if (wxTranslateMouseEvent(wxevent, window, wid, event))
+ {
+ window->GetEventHandler()->ProcessEvent(wxevent);
+ }
+ }
+ // TODO: probably the key to allowing default behaviour
+ // to happen.
+ // Say we set a m_doDefault flag to FALSE at the start of this
+ // function. Then in e.g. wxWindow::OnMouseEvent we can
+ // call Default() which sets this flag to TRUE, indicating
+ // that default processing can happen. Thus, behaviour can appear
+ // to be overridden just by adding an event handler and not calling
+ // wxWindow::OnWhatever.
+ // ALSO, maybe we can use this instead of the current way of handling
+ // drawing area events, to simplify things.
+ *continueToDispatch = True;
+}
+
+static void wxScrollBarCallback(Widget scrollbar, XtPointer clientData,
+ XmScaleCallbackStruct *cbs)
+{
+ Widget scrolledWindow = XtParent (scrollbar);
+ wxWindow *win = (wxWindow *) wxWidgetHashTable->Get ((long) scrolledWindow);
+ int orientation = (int) clientData;
+
+ wxEventType eventType = wxEVT_NULL;
+ switch (cbs->reason)
+ {
+ case XmCR_INCREMENT:
+ {
+ eventType = wxEVT_SCROLL_LINEDOWN;
+ break;
+ }
+ case XmCR_DECREMENT:
+ {
+ eventType = wxEVT_SCROLL_LINEUP;
+ break;
+ }
+ case XmCR_DRAG:
+ {
+ eventType = wxEVT_SCROLL_THUMBTRACK;
+ break;
+ }
+ case XmCR_VALUE_CHANGED:
+ {
+ // TODO: Should this be intercepted too, or will it cause
+ // duplicate events?
+ eventType = wxEVT_SCROLL_THUMBTRACK;
+ break;
+ }
+ case XmCR_PAGE_INCREMENT:
+ {
+ eventType = wxEVT_SCROLL_PAGEDOWN;
+ break;
+ }
+ case XmCR_PAGE_DECREMENT:
+ {
+ eventType = wxEVT_SCROLL_PAGEUP;
+ break;
+ }
+ case XmCR_TO_TOP:
+ {
+ eventType = wxEVT_SCROLL_TOP;
+ break;
+ }
+ case XmCR_TO_BOTTOM:
+ {
+ eventType = wxEVT_SCROLL_BOTTOM;
+ break;
+ }
+ default:
+ {
+ // Should never get here
+ wxFAIL_MSG("Unknown scroll event.");
+ break;
+ }
+ }
+
+ wxScrollEvent event(eventType, win->GetId());
+ event.SetEventObject(win);
+ event.SetPosition(cbs->value);
+ event.SetOrientation( (orientation == XmHORIZONTAL) ? wxHORIZONTAL : wxVERTICAL );
+
+ win->GetEventHandler()->ProcessEvent(event);
+}
+
+bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, Widget widget, XEvent *xevent)
+{
+ switch (xevent->xany.type)
+ {
+ case EnterNotify:
+ case LeaveNotify:
+ case ButtonPress:
+ case ButtonRelease:
+ case MotionNotify:
+ {
+ wxEventType eventType = wxEVT_NULL;
+
+ if (xevent->xany.type == LeaveNotify)
+ {
+ win->m_button1Pressed = FALSE;
+ win->m_button2Pressed = FALSE;
+ win->m_button3Pressed = FALSE;
+ return FALSE;
+ }
+ else if (xevent->xany.type == MotionNotify)
+ {
+ eventType = wxEVT_MOTION;
+ }
+ else if (xevent->xany.type == ButtonPress)
+ {
+ if (xevent->xbutton.button == Button1)
+ {
+ eventType = wxEVT_LEFT_DOWN;
+ win->m_button1Pressed = TRUE;
+ }
+ else if (xevent->xbutton.button == Button2)
+ {
+ eventType = wxEVT_MIDDLE_DOWN;
+ win->m_button2Pressed = TRUE;
+ }
+ else if (xevent->xbutton.button == Button3)
+ {
+ eventType = wxEVT_RIGHT_DOWN;
+ win->m_button3Pressed = TRUE;
+ }
+ }
+ else if (xevent->xany.type == ButtonRelease)
+ {
+ if (xevent->xbutton.button == Button1)
+ {
+ eventType = wxEVT_LEFT_UP;
+ win->m_button1Pressed = FALSE;
+ }
+ else if (xevent->xbutton.button == Button2)
+ {
+ eventType = wxEVT_MIDDLE_UP;
+ win->m_button2Pressed = FALSE;
+ }
+ else if (xevent->xbutton.button == Button3)
+ {
+ eventType = wxEVT_RIGHT_UP;
+ win->m_button3Pressed = FALSE;
+ }
+ else return FALSE;
+ }
+ else return FALSE;
+
+ wxevent.m_eventHandle = (char *)xevent;
+ wxevent.SetEventType(eventType);
+
+ Position x1, y1;
+ XtVaGetValues(widget, XmNx, &x1, XmNy, &y1, NULL);
+
+ int x2, y2;
+ win->GetPosition(&x2, &y2);
+
+ // The button x/y must be translated to wxWindows
+ // window space - the widget might be a label or button,
+ // within a form.
+ int dx = 0;
+ int dy = 0;
+ if (widget != (Widget)win->GetMainWidget())
+ {
+ dx = x1;
+ dy = y1;
+ }
+
+ wxevent.m_x = xevent->xbutton.x + dx;
+ wxevent.m_y = xevent->xbutton.y + dy;
+
+ wxevent.m_leftDown = ((eventType == wxEVT_LEFT_DOWN)
+ || (event_left_is_down (xevent)
+ && (eventType != wxEVT_LEFT_UP)));
+ wxevent.m_middleDown = ((eventType == wxEVT_MIDDLE_DOWN)
+ || (event_middle_is_down (xevent)
+ && (eventType != wxEVT_MIDDLE_UP)));
+ wxevent.m_rightDown = ((eventType == wxEVT_RIGHT_DOWN)
+ || (event_right_is_down (xevent)
+ && (eventType != wxEVT_RIGHT_UP)));
+
+ wxevent.m_shiftDown = xevent->xbutton.state & ShiftMask;
+ wxevent.m_controlDown = xevent->xbutton.state & ControlMask;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+bool wxTranslateKeyEvent(wxKeyEvent& wxevent, wxWindow *win, Widget widget, XEvent *xevent)
+{
+ switch (xevent->xany.type)
+ {
+ case KeyPress:
+ {
+ char buf[20];
+
+ KeySym keySym;
+// XComposeStatus compose;
+// (void) XLookupString ((XKeyEvent *) xevent, buf, 20, &keySym, &compose);
+ (void) XLookupString ((XKeyEvent *) xevent, buf, 20, &keySym, NULL);
+ int id = wxCharCodeXToWX (keySym);
+
+ if (xevent->xkey.state & ShiftMask)
+ wxevent.m_shiftDown = TRUE;
+ if (xevent->xkey.state & ControlMask)
+ wxevent.m_controlDown = TRUE;
+ if (xevent->xkey.state & Mod3Mask)
+ wxevent.m_altDown = TRUE;
+ if (xevent->xkey.state & Mod1Mask)
+ wxevent.m_metaDown = TRUE;
+ wxevent.SetEventObject(win);
+ wxevent.m_keyCode = id;
+ wxevent.SetTimestamp(xevent->xkey.time);
+
+ wxevent.m_x = xevent->xbutton.x;
+ wxevent.m_y = xevent->xbutton.y;
+
+ if (id > -1)
+ return TRUE;
+ else
+ return FALSE;
+ break;
+ }
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+#define YAllocColor XAllocColor
+XColor g_itemColors[5];
+int wxComputeColours (Display *display, wxColour * back, wxColour * fore)
+{
+ int result;
+ static XmColorProc colorProc;
+
+ result = wxNO_COLORS;
+
+ if (back)
+ {
+ g_itemColors[0].red = (((long) back->Red ()) << 8);
+ g_itemColors[0].green = (((long) back->Green ()) << 8);
+ g_itemColors[0].blue = (((long) back->Blue ()) << 8);
+ g_itemColors[0].flags = DoRed | DoGreen | DoBlue;
+ if (colorProc == (XmColorProc) NULL)
+ {
+ // Get a ptr to the actual function
+ colorProc = XmSetColorCalculation ((XmColorProc) NULL);
+ // And set it back to motif.
+ XmSetColorCalculation (colorProc);
+ }
+ (*colorProc) (&g_itemColors[wxBACK_INDEX],
+ &g_itemColors[wxFORE_INDEX],
+ &g_itemColors[wxSELE_INDEX],
+ &g_itemColors[wxTOPS_INDEX],
+ &g_itemColors[wxBOTS_INDEX]);
+ result = wxBACK_COLORS;
+ }
+ if (fore)
+ {
+ g_itemColors[wxFORE_INDEX].red = (((long) fore->Red ()) << 8);
+ g_itemColors[wxFORE_INDEX].green = (((long) fore->Green ()) << 8);
+ g_itemColors[wxFORE_INDEX].blue = (((long) fore->Blue ()) << 8);
+ g_itemColors[wxFORE_INDEX].flags = DoRed | DoGreen | DoBlue;
+ if (result == wxNO_COLORS)
+ result = wxFORE_COLORS;
+ }
+
+ Display *dpy = display;
+ Colormap cmap = (Colormap) wxTheApp->GetMainColormap((WXDisplay*) dpy);
+
+ if (back)
+ {
+ /* 5 Colours to allocate */
+ for (int i = 0; i < 5; i++)
+ if (!YAllocColor (dpy, cmap, &g_itemColors[i]))
+ result = wxNO_COLORS;
+ }
+ else if (fore)
+ {
+ /* Only 1 colour to allocate */
+ if (!YAllocColor (dpy, cmap, &g_itemColors[wxFORE_INDEX]))
+ result = wxNO_COLORS;
+ }
+
+ return (result);
+
+}
+
+// Changes the foreground and background colours to be derived
+// from the current background colour.
+// To change the foreground colour, you must call SetForegroundColour
+// explicitly.
+void wxWindow::ChangeBackgroundColour()
+{
+ if (GetMainWidget())
+ DoChangeBackgroundColour(GetMainWidget(), m_backgroundColour);
+}
+
+void wxWindow::ChangeForegroundColour()
+{
+ if (GetMainWidget())
+ DoChangeForegroundColour(GetMainWidget(), m_foregroundColour);
+}
+
+// Change a widget's foreground and background colours.
+
+void wxWindow::DoChangeForegroundColour(WXWidget widget, wxColour& foregroundColour)
+{
+ // When should we specify the foreground, if it's calculated
+ // by wxComputeColours?
+ // Solution: say we start with the default (computed) foreground colour.
+ // If we call SetForegroundColour explicitly for a control or window,
+ // then the foreground is changed.
+ // Therefore SetBackgroundColour computes the foreground colour, and
+ // SetForegroundColour changes the foreground colour. The ordering is
+ // important.
+
+ XtVaSetValues ((Widget) widget,
+ XmNforeground, foregroundColour.AllocColour(XtDisplay((Widget) widget)),
+ NULL);
+}
+
+void wxWindow::DoChangeBackgroundColour(WXWidget widget, wxColour& backgroundColour, bool changeArmColour)
+{
+ wxComputeColours (XtDisplay((Widget) widget), & backgroundColour,
+ (wxColour*) NULL);
+
+ XtVaSetValues ((Widget) widget,
+ XmNbackground, g_itemColors[wxBACK_INDEX].pixel,
+ XmNtopShadowColor, g_itemColors[wxTOPS_INDEX].pixel,
+ XmNbottomShadowColor, g_itemColors[wxBOTS_INDEX].pixel,
+ XmNforeground, g_itemColors[wxFORE_INDEX].pixel,
+ NULL);
+
+ if (changeArmColour)
+ XtVaSetValues ((Widget) widget,
+ XmNarmColor, g_itemColors[wxSELE_INDEX].pixel,
+ NULL);
+}
+
+void wxWindow::SetBackgroundColour(const wxColour& col)
+{
+ m_backgroundColour = col;
+ ChangeBackgroundColour();
+}
+
+void wxWindow::SetForegroundColour(const wxColour& col)
+{
+ m_foregroundColour = col;
+ ChangeForegroundColour();