+ if (orient == wxHORIZONTAL)
+ {
+ if (thumbVisible == range)
+ {
+ if (m_hScrollBar)
+ DestroyScrollbar(wxHORIZONTAL);
+ }
+ else
+ {
+ if (!m_hScrollBar)
+ CreateScrollbar(wxHORIZONTAL);
+ }
+ }
+ if (orient == wxVERTICAL)
+ {
+ if (thumbVisible == range)
+ {
+ if (m_vScrollBar)
+ DestroyScrollbar(wxVERTICAL);
+ }
+ else
+ {
+ if (!m_vScrollBar)
+ CreateScrollbar(wxVERTICAL);
+ }
+ }
+ WXWidget newScrollBar = GetScrollbar((wxOrientation)orient);
+
+ if (oldScrollBar != newScrollBar)
+ {
+ // This is important! Without it, scrollbars misbehave badly.
+ XtUnrealizeWidget((Widget) m_scrolledWindow);
+ XmScrolledWindowSetAreas ((Widget) m_scrolledWindow, (Widget) m_hScrollBar, (Widget) m_vScrollBar, (Widget) m_drawingArea);
+ XtRealizeWidget((Widget) m_scrolledWindow);
+ XtManageChild((Widget) m_scrolledWindow);
+ }
+
+ if (newScrollBar)
+ {
+ XtVaSetValues((Widget) newScrollBar,
+ XmNvalue, pos,
+ XmNminimum, 0,
+ XmNmaximum, range,
+ XmNsliderSize, thumbVisible,
+ NULL);
+ }
+
+ SetInternalScrollPos((wxOrientation)orient, pos);
+
+ int newW, newH;
+ GetSize(& newW, & newH);
+
+ // Adjusting scrollbars can resize the canvas accidentally
+ if (newW != oldW || newH != oldH)
+ SetSize(-1, -1, oldW, oldH);
+}
+
+// Does a physical scroll
+void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect)
+{
+ int x, y, w, h;
+ if (rect)
+ {
+ // Use specified rectangle
+ x = rect->x; y = rect->y; w = rect->width; h = rect->height;
+ }
+ else
+ {
+ // Use whole client area
+ x = 0; y = 0;
+ GetClientSize(& w, & h);
+ }
+
+ int x1 = (dx >= 0) ? x : x - dx;
+ int y1 = (dy >= 0) ? y : y - dy;
+ int w1 = w - abs(dx);
+ int h1 = h - abs(dy);
+ int x2 = (dx >= 0) ? x + dx : x;
+ int y2 = (dy >= 0) ? y + dy : y;
+
+ wxClientDC dc(this);
+
+ dc.SetLogicalFunction (wxCOPY);
+
+ Widget widget = (Widget) GetMainWidget();
+ Window window = XtWindow(widget);
+ Display* display = XtDisplay(widget);
+
+ XCopyArea(display, window, window, (GC) dc.GetGC(),
+ x1, y1, w1, h1, x2, y2);
+
+ dc.SetAutoSetting(true);
+ wxBrush brush(GetBackgroundColour(), wxSOLID);
+ dc.SetBrush(brush); // FIXME: needed?
+
+ wxWindowList::compatibility_iterator cnode = m_children.GetFirst();
+ while (cnode)
+ {
+ wxWindow *child = cnode->GetData();
+ int sx = 0;
+ int sy = 0;
+ child->GetSize( &sx, &sy );
+ wxPoint pos( child->GetPosition() );
+ child->SetSize( pos.x + dx, pos.y + dy, sx, sy, wxSIZE_ALLOW_MINUS_ONE );
+ cnode = cnode->GetNext();
+ }
+
+ // We'll add rectangles to the list of update rectangles according to which
+ // bits we've exposed.
+ wxList updateRects;
+
+ if (dx > 0)
+ {
+ wxRect *rect = new wxRect;
+ rect->x = x;
+ rect->y = y;
+ rect->width = dx;
+ rect->height = h;
+
+ XFillRectangle(display, window,
+ (GC) dc.GetGC(), rect->x, rect->y, rect->width, rect->height);
+
+ rect->x = rect->x;
+ rect->y = rect->y;
+ rect->width = rect->width;
+ rect->height = rect->height;
+
+ updateRects.Append((wxObject*) rect);
+ }
+ else if (dx < 0)
+ {
+ wxRect *rect = new wxRect;
+
+ rect->x = x + w + dx;
+ rect->y = y;
+ rect->width = -dx;
+ rect->height = h;
+
+ XFillRectangle(display, window,
+ (GC) dc.GetGC(), rect->x, rect->y, rect->width,
+ rect->height);
+
+ rect->x = rect->x;
+ rect->y = rect->y;
+ rect->width = rect->width;
+ rect->height = rect->height;
+
+ updateRects.Append((wxObject*) rect);
+ }
+ if (dy > 0)
+ {
+ wxRect *rect = new wxRect;
+
+ rect->x = x;
+ rect->y = y;
+ rect->width = w;
+ rect->height = dy;
+
+ XFillRectangle(display, window,
+ (GC) dc.GetGC(), rect->x, rect->y, rect->width, rect->height);
+
+ rect->x = rect->x;
+ rect->y = rect->y;
+ rect->width = rect->width;
+ rect->height = rect->height;
+
+ updateRects.Append((wxObject*) rect);
+ }
+ else if (dy < 0)
+ {
+ wxRect *rect = new wxRect;
+
+ rect->x = x;
+ rect->y = y + h + dy;
+ rect->width = w;
+ rect->height = -dy;
+
+ XFillRectangle(display, window,
+ (GC) dc.GetGC(), rect->x, rect->y, rect->width, rect->height);
+
+ rect->x = rect->x;
+ rect->y = rect->y;
+ rect->width = rect->width;
+ rect->height = rect->height;
+
+ updateRects.Append((wxObject*) rect);
+ }
+ dc.SetBrush(wxNullBrush);
+
+ // Now send expose events
+
+ wxList::compatibility_iterator node = updateRects.GetFirst();
+ while (node)
+ {
+ wxRect* rect = (wxRect*) node->GetData();
+ XExposeEvent event;
+
+ event.type = Expose;
+ event.display = display;
+ event.send_event = True;
+ event.window = window;
+
+ event.x = rect->x;
+ event.y = rect->y;
+ event.width = rect->width;
+ event.height = rect->height;
+
+ event.count = 0;
+
+ XSendEvent(display, window, False, ExposureMask, (XEvent *)&event);
+
+ node = node->GetNext();
+
+ }
+
+ // Delete the update rects
+ node = updateRects.GetFirst();
+ while (node)
+ {
+ wxRect* rect = (wxRect*) node->GetData();
+ delete rect;
+ node = node->GetNext();
+ }
+
+ XmUpdateDisplay((Widget) GetMainWidget());
+}
+
+// ---------------------------------------------------------------------------
+// drag and drop
+// ---------------------------------------------------------------------------
+
+#if wxUSE_DRAG_AND_DROP
+
+void wxWindow::SetDropTarget(wxDropTarget * WXUNUSED(pDropTarget))
+{
+ // TODO
+}
+
+#endif
+
+// Old style file-manager drag&drop
+void wxWindow::DragAcceptFiles(bool WXUNUSED(accept))
+{
+ // TODO
+}
+
+// ----------------------------------------------------------------------------
+// tooltips
+// ----------------------------------------------------------------------------
+
+#if wxUSE_TOOLTIPS
+
+void wxWindow::DoSetToolTip(wxToolTip * WXUNUSED(tooltip))
+{
+ // TODO
+}
+
+#endif // wxUSE_TOOLTIPS
+
+// ----------------------------------------------------------------------------
+// popup menus
+// ----------------------------------------------------------------------------
+
+#if wxUSE_MENUS
+
+bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y)
+{
+ if ( x == -1 && y == -1 )
+ {
+ wxPoint mouse = ScreenToClient(wxGetMousePosition());
+ x = mouse.x; y = mouse.y;
+ }
+
+ Widget widget = (Widget) GetMainWidget();
+
+ /* The menuId field seems to be usused, so we'll use it to
+ indicate whether a menu is popped up or not:
+ 0: Not currently created as a popup
+ -1: Created as a popup, but not active
+ 1: Active popup.
+ */
+
+ if (menu->GetParent() && (menu->GetId() != -1))
+ return false;
+
+ if (menu->GetMainWidget())
+ {
+ menu->DestroyMenu(true);
+ }
+
+ menu->SetId(1); /* Mark as popped-up */
+ menu->CreateMenu(NULL, widget, menu);
+ menu->SetInvokingWindow(this);
+
+ menu->UpdateUI();
+
+ // menu->SetParent(parent);
+ // parent->children->Append(menu); // Store menu for later deletion
+
+ Widget menuWidget = (Widget) menu->GetMainWidget();
+
+ int rootX = 0;
+ int rootY = 0;
+
+ int deviceX = x;
+ int deviceY = y;
+ /*
+ if (this->IsKindOf(CLASSINFO(wxCanvas)))
+ {
+ wxCanvas *canvas = (wxCanvas *) this;
+ deviceX = canvas->GetDC ()->LogicalToDeviceX (x);
+ deviceY = canvas->GetDC ()->LogicalToDeviceY (y);
+ }
+ */
+
+ Display *display = XtDisplay (widget);
+ Window rootWindow = RootWindowOfScreen (XtScreen((Widget)widget));
+ Window thisWindow = XtWindow (widget);
+ Window childWindow;
+ XTranslateCoordinates (display, thisWindow, rootWindow, (int) deviceX, (int) deviceY,
+ &rootX, &rootY, &childWindow);
+
+ XButtonPressedEvent event;
+ event.type = ButtonPress;
+ event.button = 1;
+
+ event.x = deviceX;
+ event.y = deviceY;
+
+ event.x_root = rootX;
+ event.y_root = rootY;
+
+ XmMenuPosition (menuWidget, &event);
+ XtManageChild (menuWidget);
+
+ // The ID of a pop-up menu is 1 when active, and is set to 0 by the
+ // idle-time destroy routine.
+ // Waiting until this ID changes causes this function to block until
+ // the menu has been dismissed and the widgets cleaned up.
+ // In other words, once this routine returns, it is safe to delete
+ // the menu object.
+ // Ian Brown <ian.brown@printsoft.de>
+
+ wxEventLoop evtLoop;
+
+ while (menu->GetId() == 1)
+ {
+ wxDoEventLoopIteration( evtLoop );
+ }
+
+ return true;
+}
+
+#endif
+
+// ---------------------------------------------------------------------------
+// moving and resizing
+// ---------------------------------------------------------------------------
+
+bool wxWindow::PreResize()
+{
+ return true;
+}
+
+// Get total size
+void wxWindow::DoGetSize(int *x, int *y) const
+{
+ Widget widget = (Widget)( !m_drawingArea ? GetTopWidget() :
+ ( m_borderWidget ? m_borderWidget :
+ m_scrolledWindow ? m_scrolledWindow :
+ m_drawingArea ) );
+ Dimension xx, yy;
+
+ XtVaGetValues( widget,
+ XmNwidth, &xx,
+ XmNheight, &yy,
+ NULL );
+ if(x) *x = xx;
+ if(y) *y = yy;
+}
+
+void wxWindow::DoGetPosition(int *x, int *y) const
+{
+ Widget widget = (Widget)
+ ( m_drawingArea ?
+ ( m_borderWidget ? m_borderWidget : m_scrolledWindow ) :
+ GetTopWidget() );
+
+ Position xx, yy;
+ XtVaGetValues(widget, 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;
+ }
+
+ if(x) *x = xx;
+ if(y) *y = yy;
+}
+
+void wxWindow::DoScreenToClient(int *x, int *y) const
+{
+ Widget widget = (Widget) GetClientWidget();
+ Display *display = XtDisplay((Widget) GetMainWidget());
+ Window rootWindow = RootWindowOfScreen(XtScreen(widget));
+ Window thisWindow = XtWindow(widget);
+
+ Window childWindow;
+ int xx = *x;
+ int yy = *y;
+ XTranslateCoordinates(display, rootWindow, thisWindow, xx, yy, x, y, &childWindow);
+}
+
+void wxWindow::DoClientToScreen(int *x, int *y) const
+{
+ Widget widget = (Widget) GetClientWidget();
+ Display *display = XtDisplay(widget);
+ Window rootWindow = RootWindowOfScreen(XtScreen(widget));
+ Window thisWindow = XtWindow(widget);
+
+ Window childWindow;
+ int xx = *x;
+ int yy = *y;
+ XTranslateCoordinates(display, thisWindow, rootWindow, xx, yy, x, y, &childWindow);
+}
+
+
+// Get size *available for subwindows* i.e. excluding menu bar etc.
+void wxWindow::DoGetClientSize(int *x, int *y) const
+{
+ Widget widget = (Widget) GetClientWidget();
+ Dimension xx, yy;
+ XtVaGetValues(widget, XmNwidth, &xx, XmNheight, &yy, NULL);
+ if(x) *x = xx; if(y) *y = yy;
+}
+
+void wxWindow::DoSetSize(int x, int y, int width, int height, int sizeFlags)
+{
+ DoSetSizeIntr(x, y, width, height, sizeFlags, false);
+}
+
+void wxWindow::DoSetSizeIntr(int x, int y, int width, int height,
+ int sizeFlags, bool fromCtor)
+{
+ // A bit of optimization to help sort out the flickers.
+ int oldX = -1, oldY = -1, oldW = -1, oldH = -1;
+ if( !fromCtor )
+ {
+ GetSize(& oldW, & oldH);
+ GetPosition(& oldX, & oldY);
+ }
+
+ if ( !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
+ {
+ if ( x == -1 )
+ x = oldX;
+ if ( y == -1 )
+ y = oldY;
+ }
+
+ wxSize size(-1, -1);
+ if ( width <= 0 )
+ {
+ if ( ( sizeFlags & wxSIZE_AUTO_WIDTH ) && !fromCtor )
+ {
+ size = DoGetBestSize();
+ width = size.x;
+ }
+ else
+ {
+ width = oldW;