]> git.saurik.com Git - wxWidgets.git/blob - src/x11/window.cpp
54f29ea892b20541b56ebb2a2abaf31072915434
[wxWidgets.git] / src / x11 / window.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: windows.cpp
3 // Purpose: wxWindow
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 17/09/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "window.h"
22 #endif
23
24 #include "wx/setup.h"
25 #include "wx/menu.h"
26 #include "wx/dc.h"
27 #include "wx/dcclient.h"
28 #include "wx/utils.h"
29 #include "wx/app.h"
30 #include "wx/panel.h"
31 #include "wx/layout.h"
32 #include "wx/dialog.h"
33 #include "wx/listbox.h"
34 #include "wx/button.h"
35 #include "wx/settings.h"
36 #include "wx/msgdlg.h"
37 #include "wx/frame.h"
38 #include "wx/scrolwin.h"
39 #include "wx/module.h"
40 #include "wx/menuitem.h"
41 #include "wx/log.h"
42
43 #if wxUSE_DRAG_AND_DROP
44 #include "wx/dnd.h"
45 #endif
46
47 #include "wx/x11/private.h"
48
49 #include <string.h>
50
51 // ----------------------------------------------------------------------------
52 // constants
53 // ----------------------------------------------------------------------------
54
55 static const int SCROLL_MARGIN = 4;
56
57 // ----------------------------------------------------------------------------
58 // global variables for this module
59 // ----------------------------------------------------------------------------
60
61 extern wxHashTable *wxWidgetHashTable;
62 static wxWindow* g_captureWindow = NULL;
63
64
65 // ----------------------------------------------------------------------------
66 // private functions
67 // ----------------------------------------------------------------------------
68
69 static void wxCanvasRepaintProc(Widget, XtPointer, XmDrawingAreaCallbackStruct * cbs);
70 static void wxCanvasInputEvent(Widget drawingArea, XtPointer data, XmDrawingAreaCallbackStruct * cbs);
71 static void wxCanvasMotionEvent(Widget, XButtonEvent * event);
72 static void wxCanvasEnterLeave(Widget drawingArea, XtPointer clientData, XCrossingEvent * event);
73 static void wxScrollBarCallback(Widget widget, XtPointer clientData,
74 XmScrollBarCallbackStruct *cbs);
75 static void wxPanelItemEventHandler(Widget wid,
76 XtPointer client_data,
77 XEvent* event,
78 Boolean *continueToDispatch);
79
80 // ----------------------------------------------------------------------------
81 // macros
82 // ----------------------------------------------------------------------------
83
84 #define event_left_is_down(x) ((x)->xbutton.state & Button1Mask)
85 #define event_middle_is_down(x) ((x)->xbutton.state & Button2Mask)
86 #define event_right_is_down(x) ((x)->xbutton.state & Button3Mask)
87
88 // ----------------------------------------------------------------------------
89 // event tables
90 // ----------------------------------------------------------------------------
91
92 IMPLEMENT_DYNAMIC_CLASS(wxWindowX11, wxWindowBase)
93
94 BEGIN_EVENT_TABLE(wxWindowX11, wxWindowBase)
95 EVT_SYS_COLOUR_CHANGED(wxWindowX11::OnSysColourChanged)
96 EVT_IDLE(wxWindowX11::OnIdle)
97 END_EVENT_TABLE()
98
99 // ============================================================================
100 // implementation
101 // ============================================================================
102
103 // ----------------------------------------------------------------------------
104 // helper functions
105 // ----------------------------------------------------------------------------
106
107 // ----------------------------------------------------------------------------
108 // constructors
109 // ----------------------------------------------------------------------------
110
111 void wxWindowX11::Init()
112 {
113 // generic initializations first
114 InitBase();
115
116 // Motif-specific
117 m_needsRefresh = TRUE;
118 m_mainWidget = (WXWidget) 0;
119
120 m_button1Pressed =
121 m_button2Pressed =
122 m_button3Pressed = FALSE;
123
124 m_winCaptured = FALSE;
125
126 m_isShown = TRUE;
127 m_isBeingDeleted = FALSE;
128
129 m_hScrollBar =
130 m_vScrollBar =
131 m_borderWidget =
132 m_scrolledWindow =
133 m_drawingArea = (WXWidget) 0;
134
135 m_hScroll =
136 m_vScroll = FALSE;
137
138 m_scrollPosX =
139 m_scrollPosY = 0;
140
141 m_backingPixmap = (WXPixmap) 0;
142 m_pixmapWidth =
143 m_pixmapHeight = 0;
144
145 m_pixmapOffsetX =
146 m_pixmapOffsetY = 0;
147
148 m_lastTS = 0;
149 m_lastButton = 0;
150 m_canAddEventHandler = FALSE;
151 }
152
153 // real construction (Init() must have been called before!)
154 bool wxWindowX11::Create(wxWindow *parent, wxWindowID id,
155 const wxPoint& pos,
156 const wxSize& size,
157 long style,
158 const wxString& name)
159 {
160 wxCHECK_MSG( parent, FALSE, "can't create wxWindow without parent" );
161
162 CreateBase(parent, id, pos, size, style, wxDefaultValidator, name);
163
164 parent->AddChild(this);
165
166 m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
167 m_foregroundColour = *wxBLACK;
168
169 if (style & wxSIMPLE_BORDER)
170 {
171 } else if (style & wxSUNKEN_BORDER)
172 {
173 } else if (style & wxRAISED_BORDER)
174 {
175 }
176
177 // TODO: create XWindow
178
179 #if 0
180 wxAddWindowToTable((Window) m_drawingArea, this);
181 wxAddWindowToTable((Window) m_scrolledWindow, this);
182 #endif
183
184 // Without this, the cursor may not be restored properly (e.g. in splitter
185 // sample).
186 SetCursor(*wxSTANDARD_CURSOR);
187 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
188 SetSize(pos.x, pos.y, size.x, size.y);
189
190 return TRUE;
191 }
192
193 // Destructor
194 wxWindowX11::~wxWindow()
195 {
196 if (g_captureWindow == this)
197 g_captureWindow = NULL;
198
199 m_isBeingDeleted = TRUE;
200
201 // Motif-specific actions first
202 WXWindow wMain = GetMainWindow();
203 if ( wMain )
204 {
205 // Removes event handlers
206 //DetachWidget(wMain);
207 }
208
209 ClearUpdateRects();
210
211 if ( m_parent )
212 m_parent->RemoveChild( this );
213
214 // TODO
215
216 #if 0
217 // If m_drawingArea, we're a fully-fledged window with drawing area,
218 // scrollbars etc. (what wxCanvas used to be)
219 if ( m_drawingArea )
220 {
221 // Destroy children before destroying self
222 DestroyChildren();
223
224 if (m_backingPixmap)
225 XFreePixmap (XtDisplay ((Widget) GetMainWidget()), (Pixmap) m_backingPixmap);
226
227 Widget w = (Widget) m_drawingArea;
228 wxDeleteWindowFromTable(w);
229
230 if (w)
231 {
232 XtDestroyWidget(w);
233 m_drawingArea = (WXWidget) 0;
234 }
235
236 // Only if we're _really_ a canvas (not a dialog box/panel)
237 if (m_scrolledWindow)
238 {
239 wxDeleteWindowFromTable((Widget) m_scrolledWindow);
240 }
241
242 if (m_hScrollBar)
243 {
244 wxDeleteWindowFromTable((Widget) m_hScrollBar);
245 XtUnmanageChild((Widget) m_hScrollBar);
246 }
247 if (m_vScrollBar)
248 {
249 wxDeleteWindowFromTable((Widget) m_vScrollBar);
250 XtUnmanageChild((Widget) m_vScrollBar);
251 }
252
253 if (m_hScrollBar)
254 XtDestroyWidget((Widget) m_hScrollBar);
255 if (m_vScrollBar)
256 XtDestroyWidget((Widget) m_vScrollBar);
257
258 UnmanageAndDestroy(m_scrolledWindow);
259
260 if (m_borderWidget)
261 {
262 XtDestroyWidget ((Widget) m_borderWidget);
263 m_borderWidget = (WXWidget) 0;
264 }
265 }
266 else // Why wasn't this here before? JACS 8/3/2000
267 #endif
268 DestroyChildren();
269
270
271 // Destroy the window
272 if (GetMainWindow())
273 {
274 // TODO
275 // XtDestroyWidget((Widget) GetMainWidget());
276 SetMainWindow((WXWindow) NULL);
277 }
278 }
279
280 // ----------------------------------------------------------------------------
281 // scrollbar management
282 // ----------------------------------------------------------------------------
283
284 // Helper function
285 void wxWindowX11::CreateScrollbar(wxOrientation orientation)
286 {
287 // TODO
288 #if 0
289 wxCHECK_RET( m_drawingArea, "this window can't have scrollbars" );
290
291 XtVaSetValues((Widget) m_scrolledWindow, XmNresizePolicy, XmRESIZE_NONE, NULL);
292
293 // Add scrollbars if required
294 if (orientation == wxHORIZONTAL)
295 {
296 Widget hScrollBar = XtVaCreateManagedWidget ("hsb",
297 xmScrollBarWidgetClass, (Widget) m_scrolledWindow,
298 XmNorientation, XmHORIZONTAL,
299 NULL);
300 XtAddCallback (hScrollBar, XmNvalueChangedCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
301 XtAddCallback (hScrollBar, XmNdragCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
302 XtAddCallback (hScrollBar, XmNincrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
303 XtAddCallback (hScrollBar, XmNdecrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
304 XtAddCallback (hScrollBar, XmNpageIncrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
305 XtAddCallback (hScrollBar, XmNpageDecrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
306 XtAddCallback (hScrollBar, XmNtoTopCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
307 XtAddCallback (hScrollBar, XmNtoBottomCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
308
309 XtVaSetValues (hScrollBar,
310 XmNincrement, 1,
311 XmNvalue, 0,
312 NULL);
313
314 m_hScrollBar = (WXWidget) hScrollBar;
315
316 wxColour backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
317 DoChangeBackgroundColour(m_hScrollBar, backgroundColour, TRUE);
318
319 XtRealizeWidget(hScrollBar);
320
321 XtVaSetValues((Widget) m_scrolledWindow,
322 XmNhorizontalScrollBar, (Widget) m_hScrollBar,
323 NULL);
324
325 m_hScroll = TRUE;
326
327 wxAddWindowToTable( hScrollBar, this );
328 }
329
330 if (orientation == wxVERTICAL)
331 {
332 Widget vScrollBar = XtVaCreateManagedWidget ("vsb",
333 xmScrollBarWidgetClass, (Widget) m_scrolledWindow,
334 XmNorientation, XmVERTICAL,
335 NULL);
336 XtAddCallback (vScrollBar, XmNvalueChangedCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
337 XtAddCallback (vScrollBar, XmNdragCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
338 XtAddCallback (vScrollBar, XmNincrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
339 XtAddCallback (vScrollBar, XmNdecrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
340 XtAddCallback (vScrollBar, XmNpageIncrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
341 XtAddCallback (vScrollBar, XmNpageDecrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
342 XtAddCallback (vScrollBar, XmNtoTopCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
343 XtAddCallback (vScrollBar, XmNtoBottomCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
344
345 XtVaSetValues (vScrollBar,
346 XmNincrement, 1,
347 XmNvalue, 0,
348 NULL);
349
350 m_vScrollBar = (WXWidget) vScrollBar;
351 wxColour backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
352 DoChangeBackgroundColour(m_vScrollBar, backgroundColour, TRUE);
353
354 XtRealizeWidget(vScrollBar);
355
356 XtVaSetValues((Widget) m_scrolledWindow,
357 XmNverticalScrollBar, (Widget) m_vScrollBar,
358 NULL);
359
360 m_vScroll = TRUE;
361
362 wxAddWindowToTable( vScrollBar, this );
363 }
364
365 XtVaSetValues((Widget) m_scrolledWindow, XmNresizePolicy, XmRESIZE_ANY, NULL);
366 #endif
367 }
368
369 void wxWindowX11::DestroyScrollbar(wxOrientation orientation)
370 {
371 // TODO
372 #if 0
373 wxCHECK_RET( m_drawingArea, "this window can't have scrollbars" );
374
375 XtVaSetValues((Widget) m_scrolledWindow, XmNresizePolicy, XmRESIZE_NONE, NULL);
376 // Add scrollbars if required
377 if (orientation == wxHORIZONTAL)
378 {
379 if (m_hScrollBar)
380 {
381 wxDeleteWindowFromTable((Widget)m_hScrollBar);
382 XtDestroyWidget((Widget) m_hScrollBar);
383 }
384 m_hScrollBar = (WXWidget) 0;
385 m_hScroll = FALSE;
386
387 XtVaSetValues((Widget) m_scrolledWindow,
388 XmNhorizontalScrollBar, (Widget) 0,
389 NULL);
390
391 }
392
393 if (orientation == wxVERTICAL)
394 {
395 if (m_vScrollBar)
396 {
397 wxDeleteWindowFromTable((Widget)m_vScrollBar);
398 XtDestroyWidget((Widget) m_vScrollBar);
399 }
400 m_vScrollBar = (WXWidget) 0;
401 m_vScroll = FALSE;
402
403 XtVaSetValues((Widget) m_scrolledWindow,
404 XmNverticalScrollBar, (Widget) 0,
405 NULL);
406
407 }
408 XtVaSetValues((Widget) m_scrolledWindow, XmNresizePolicy, XmRESIZE_ANY, NULL);
409 #endif
410 }
411
412 // ---------------------------------------------------------------------------
413 // basic operations
414 // ---------------------------------------------------------------------------
415
416 void wxWindowX11::SetFocus()
417 {
418 // TODO
419 #if 0
420 Widget wMain = (Widget) GetMainWidget();
421 XmProcessTraversal(wMain, XmTRAVERSE_CURRENT);
422 XmProcessTraversal((Widget) GetMainWidget(), XmTRAVERSE_CURRENT);
423 #endif
424 }
425
426 // Get the window with the focus
427 wxWindow *wxWindowBase::FindFocus()
428 {
429 // TODO
430 return NULL;
431 #if 0
432
433 // TODO Problems:
434 // (1) Can there be multiple focussed widgets in an application?
435 // In which case we need to find the top-level window that's
436 // currently active.
437 // (2) The widget with the focus may not be in the widget table
438 // depending on which widgets I put in the table
439 wxWindow *winFocus = (wxWindow *)NULL;
440 for ( wxWindowList::Node *node = wxTopLevelWindows.GetFirst();
441 node;
442 node = node->GetNext() )
443 {
444 wxWindow *win = node->GetData();
445
446 Widget w = XmGetFocusWidget ((Widget) win->GetTopWidget());
447
448 if (w != (Widget) NULL)
449 {
450 winFocus = wxGetWindowFromTable(w);
451 if ( winFocus )
452 break;
453 }
454 }
455
456 return winFocus;
457 #endif
458 }
459
460 bool wxWindowX11::Enable(bool enable)
461 {
462 if ( !wxWindowBase::Enable(enable) )
463 return FALSE;
464
465 // TODO
466 #if 0
467 Widget wMain = (Widget)GetMainWidget();
468 if ( wMain )
469 {
470 XtSetSensitive(wMain, enable);
471 XmUpdateDisplay(wMain);
472 }
473 #endif
474
475 return TRUE;
476 }
477
478 bool wxWindowX11::Show(bool show)
479 {
480 if ( !wxWindowBase::Show(show) )
481 return FALSE;
482
483 Window xwin = (Window) GetXWindow();
484 Display *xdisp = (Display*) GetXDisplay();
485 if (show)
486 XMapWindow(xdisp, xwin);
487 else
488 XUnmapWindow(xdisp, xwin);
489
490 return TRUE;
491 }
492
493 // Raise the window to the top of the Z order
494 void wxWindowX11::Raise()
495 {
496 Window window = GetTopWindow();
497 if (window)
498 XRaiseWindow(wxGetDisplay(), window);
499 }
500
501 // Lower the window to the bottom of the Z order
502 void wxWindowX11::Lower()
503 {
504 Window window = GetTopWindow();
505 if (window)
506 XLowerWindow(wxGetDisplay(), window);
507 }
508
509 void wxWindowX11::SetTitle(const wxString& title)
510 {
511 // TODO
512 // XtVaSetValues((Widget)GetMainWidget(), XmNtitle, title.c_str(), NULL);
513 }
514
515 wxString wxWindowX11::GetTitle() const
516 {
517 // TODO
518 return wxEmptyString;
519 #if 0
520 char *title;
521 XtVaGetValues((Widget)GetMainWidget(), XmNtitle, &title, NULL);
522
523 return wxString(title);
524 #endif
525 }
526
527 void wxWindowX11::DoCaptureMouse()
528 {
529 g_captureWindow = this;
530 if ( m_winCaptured )
531 return;
532
533 // TODO
534 #if 0
535 Widget wMain = (Widget)GetMainWidget();
536 if ( wMain )
537 XtAddGrab(wMain, TRUE, FALSE);
538 #endif
539
540 m_winCaptured = TRUE;
541 }
542
543 void wxWindowX11::DoReleaseMouse()
544 {
545 g_captureWindow = NULL;
546 if ( !m_winCaptured )
547 return;
548
549 // TODO
550 #if 0
551 Widget wMain = (Widget)GetMainWidget();
552 if ( wMain )
553 XtRemoveGrab(wMain);
554 #endif
555
556 m_winCaptured = FALSE;
557 }
558
559 bool wxWindowX11::SetFont(const wxFont& font)
560 {
561 if ( !wxWindowBase::SetFont(font) )
562 {
563 // nothing to do
564 return FALSE;
565 }
566
567 ChangeFont();
568
569 return TRUE;
570 }
571
572 bool wxWindowX11::SetCursor(const wxCursor& cursor)
573 {
574 if ( !wxWindowBase::SetCursor(cursor) )
575 {
576 // no change
577 return FALSE;
578 }
579
580 wxCursor* cursor2 = NULL;
581 if (m_cursor.Ok())
582 cursor2 = & m_cursor;
583 else
584 cursor2 = wxSTANDARD_CURSOR;
585
586 WXDisplay *dpy = GetXDisplay();
587 WXCursor x_cursor = cursor2->GetXCursor(dpy);
588
589 Window win = (Window) GetMainWindow();
590 XDefineCursor((Display*) dpy, win, (Cursor) x_cursor);
591
592 return TRUE;
593 }
594
595 // Coordinates relative to the window
596 void wxWindowX11::WarpPointer (int x, int y)
597 {
598 Window wClient = (Window) GetClientWindow();
599
600 XWarpPointer(wxGetDisplay(), None, wClient, 0, 0, 0, 0, x, y);
601 }
602
603 // ---------------------------------------------------------------------------
604 // scrolling stuff
605 // ---------------------------------------------------------------------------
606
607 int wxWindowX11::GetScrollPos(int orient) const
608 {
609 if (orient == wxHORIZONTAL)
610 return m_scrollPosX;
611 else
612 return m_scrollPosY;
613 }
614
615 // This now returns the whole range, not just the number of positions that we
616 // can scroll.
617 int wxWindowX11::GetScrollRange(int WXUNUSED(orient)) const
618 {
619 // TODO
620 return 0;
621 #if 0
622 Widget scrollBar = (Widget)GetScrollbar((wxOrientation)orient);
623 wxCHECK_MSG( scrollBar, 0, "no such scrollbar" );
624
625 int range;
626 XtVaGetValues(scrollBar, XmNmaximum, &range, NULL);
627 return range;
628 #endif
629 }
630
631 int wxWindowX11::GetScrollThumb(int orient) const
632 {
633 // TODO
634 return 0;
635
636 #if 0
637 Widget scrollBar = (Widget)GetScrollbar((wxOrientation)orient);
638 wxCHECK_MSG( scrollBar, 0, "no such scrollbar" );
639
640 int thumb;
641 XtVaGetValues(scrollBar, XmNsliderSize, &thumb, NULL);
642 return thumb;
643 #endif
644 }
645
646 void wxWindowX11::SetScrollPos(int WXUNUSED(orient), int WXUNUSED(pos), bool WXUNUSED(refresh))
647 {
648 // TODO
649
650 #if 0
651 Widget scrollBar = (Widget)GetScrollbar((wxOrientation)orient);
652
653 if ( scrollBar )
654 {
655 XtVaSetValues (scrollBar, XmNvalue, pos, NULL);
656 }
657 #endif
658 SetInternalScrollPos((wxOrientation)orient, pos);
659 }
660
661 // New function that will replace some of the above.
662 void wxWindowX11::SetScrollbar(int WXUNUSED(orient), int WXUNUSED(pos), int WXUNUSED(thumbVisible),
663 int WXUNUSED(range), bool WXUNUSED(refresh))
664 {
665 // TODO
666 #if 0
667 int oldW, oldH;
668 GetSize(& oldW, & oldH);
669
670 if (range == 0)
671 range = 1;
672 if (thumbVisible == 0)
673 thumbVisible = 1;
674
675 if (thumbVisible > range)
676 thumbVisible = range;
677
678 // Save the old state to see if it changed
679 WXWidget oldScrollBar = GetScrollbar((wxOrientation)orient);
680
681 if (orient == wxHORIZONTAL)
682 {
683 if (thumbVisible == range)
684 {
685 if (m_hScrollBar)
686 DestroyScrollbar(wxHORIZONTAL);
687 }
688 else
689 {
690 if (!m_hScrollBar)
691 CreateScrollbar(wxHORIZONTAL);
692 }
693 }
694 if (orient == wxVERTICAL)
695 {
696 if (thumbVisible == range)
697 {
698 if (m_vScrollBar)
699 DestroyScrollbar(wxVERTICAL);
700 }
701 else
702 {
703 if (!m_vScrollBar)
704 CreateScrollbar(wxVERTICAL);
705 }
706 }
707 WXWidget newScrollBar = GetScrollbar((wxOrientation)orient);
708
709 if (oldScrollBar != newScrollBar)
710 {
711 // This is important! Without it, scrollbars misbehave badly.
712 XtUnrealizeWidget((Widget) m_scrolledWindow);
713 XmScrolledWindowSetAreas ((Widget) m_scrolledWindow, (Widget) m_hScrollBar, (Widget) m_vScrollBar, (Widget) m_drawingArea);
714 XtRealizeWidget((Widget) m_scrolledWindow);
715 XtManageChild((Widget) m_scrolledWindow);
716 }
717
718 if (newScrollBar)
719 {
720 XtVaSetValues((Widget) newScrollBar,
721 XmNvalue, pos,
722 XmNminimum, 0,
723 XmNmaximum, range,
724 XmNsliderSize, thumbVisible,
725 NULL);
726 }
727
728 SetInternalScrollPos((wxOrientation)orient, pos);
729
730 int newW, newH;
731 GetSize(& newW, & newH);
732
733 // Adjusting scrollbars can resize the canvas accidentally
734 if (newW != oldW || newH != oldH)
735 SetSize(-1, -1, oldW, oldH);
736 #endif
737 }
738
739 // Does a physical scroll
740 void wxWindowX11::ScrollWindow(int dx, int dy, const wxRect *rect)
741 {
742 int x, y, w, h;
743 if (rect)
744 {
745 // Use specified rectangle
746 x = rect->x; y = rect->y; w = rect->width; h = rect->height;
747 }
748 else
749 {
750 // Use whole client area
751 x = 0; y = 0;
752 GetClientSize(& w, & h);
753 }
754
755 wxNode *cnode = m_children.First();
756 while (cnode)
757 {
758 wxWindow *child = (wxWindow*) cnode->Data();
759 int sx = 0;
760 int sy = 0;
761 child->GetSize( &sx, &sy );
762 wxPoint pos( child->GetPosition() );
763 child->SetSize( pos.x + dx, pos.y + dy, sx, sy, wxSIZE_ALLOW_MINUS_ONE );
764 cnode = cnode->Next();
765 }
766
767 int x1 = (dx >= 0) ? x : x - dx;
768 int y1 = (dy >= 0) ? y : y - dy;
769 int w1 = w - abs(dx);
770 int h1 = h - abs(dy);
771 int x2 = (dx >= 0) ? x + dx : x;
772 int y2 = (dy >= 0) ? y + dy : y;
773
774 wxClientDC dc(this);
775
776 dc.SetLogicalFunction (wxCOPY);
777
778 Window window = (Window) GetMainWindow();
779 Display* display = wxGetDisplay();
780
781 XCopyArea(display, window, window, (GC) dc.GetGC(),
782 x1, y1, w1, h1, x2, y2);
783
784 dc.SetAutoSetting(TRUE);
785 wxBrush brush(GetBackgroundColour(), wxSOLID);
786 dc.SetBrush(brush); // FIXME: needed?
787
788 // We'll add rectangles to the list of update rectangles according to which
789 // bits we've exposed.
790 wxList updateRects;
791
792 if (dx > 0)
793 {
794 wxRect *rect = new wxRect;
795 rect->x = x;
796 rect->y = y;
797 rect->width = dx;
798 rect->height = h;
799
800 XFillRectangle(display, window,
801 (GC) dc.GetGC(), rect->x, rect->y, rect->width, rect->height);
802
803 rect->x = rect->x;
804 rect->y = rect->y;
805 rect->width = rect->width;
806 rect->height = rect->height;
807
808 updateRects.Append((wxObject*) rect);
809 }
810 else if (dx < 0)
811 {
812 wxRect *rect = new wxRect;
813
814 rect->x = x + w + dx;
815 rect->y = y;
816 rect->width = -dx;
817 rect->height = h;
818
819 XFillRectangle(display, window,
820 (GC) dc.GetGC(), rect->x, rect->y, rect->width,
821 rect->height);
822
823 rect->x = rect->x;
824 rect->y = rect->y;
825 rect->width = rect->width;
826 rect->height = rect->height;
827
828 updateRects.Append((wxObject*) rect);
829 }
830 if (dy > 0)
831 {
832 wxRect *rect = new wxRect;
833
834 rect->x = x;
835 rect->y = y;
836 rect->width = w;
837 rect->height = dy;
838
839 XFillRectangle(display, window,
840 (GC) dc.GetGC(), rect->x, rect->y, rect->width, rect->height);
841
842 rect->x = rect->x;
843 rect->y = rect->y;
844 rect->width = rect->width;
845 rect->height = rect->height;
846
847 updateRects.Append((wxObject*) rect);
848 }
849 else if (dy < 0)
850 {
851 wxRect *rect = new wxRect;
852
853 rect->x = x;
854 rect->y = y + h + dy;
855 rect->width = w;
856 rect->height = -dy;
857
858 XFillRectangle(display, window,
859 (GC) dc.GetGC(), rect->x, rect->y, rect->width, rect->height);
860
861 rect->x = rect->x;
862 rect->y = rect->y;
863 rect->width = rect->width;
864 rect->height = rect->height;
865
866 updateRects.Append((wxObject*) rect);
867 }
868 dc.SetBrush(wxNullBrush);
869
870 // Now send expose events
871
872 wxNode* node = updateRects.First();
873 while (node)
874 {
875 wxRect* rect = (wxRect*) node->Data();
876 XExposeEvent event;
877
878 event.type = Expose;
879 event.display = display;
880 event.send_event = True;
881 event.window = window;
882
883 event.x = rect->x;
884 event.y = rect->y;
885 event.width = rect->width;
886 event.height = rect->height;
887
888 event.count = 0;
889
890 XSendEvent(display, window, False, ExposureMask, (XEvent *)&event);
891
892 node = node->Next();
893
894 }
895
896 // Delete the update rects
897 node = updateRects.First();
898 while (node)
899 {
900 wxRect* rect = (wxRect*) node->Data();
901 delete rect;
902 node = node->Next();
903 }
904
905 // TODO
906
907 // XmUpdateDisplay((Widget) GetMainWidget());
908 }
909
910 // ---------------------------------------------------------------------------
911 // drag and drop
912 // ---------------------------------------------------------------------------
913
914 #if wxUSE_DRAG_AND_DROP
915
916 void wxWindowX11::SetDropTarget(wxDropTarget * WXUNUSED(pDropTarget))
917 {
918 // TODO
919 }
920
921 #endif
922
923 // Old style file-manager drag&drop
924 void wxWindowX11::DragAcceptFiles(bool WXUNUSED(accept))
925 {
926 // TODO
927 }
928
929 // ----------------------------------------------------------------------------
930 // tooltips
931 // ----------------------------------------------------------------------------
932
933 #if wxUSE_TOOLTIPS
934
935 void wxWindowX11::DoSetToolTip(wxToolTip * WXUNUSED(tooltip))
936 {
937 // TODO
938 }
939
940 #endif // wxUSE_TOOLTIPS
941
942 // ---------------------------------------------------------------------------
943 // moving and resizing
944 // ---------------------------------------------------------------------------
945
946 bool wxWindowX11::PreResize()
947 {
948 return TRUE;
949 }
950
951 // Get total size
952 void wxWindowX11::DoGetSize(int *x, int *y) const
953 {
954 // TODO
955 #if 0
956 if (m_drawingArea)
957 {
958 CanvasGetSize(x, y);
959 return;
960 }
961
962 Widget widget = (Widget) GetTopWidget();
963 Dimension xx, yy;
964 XtVaGetValues(widget, XmNwidth, &xx, XmNheight, &yy, NULL);
965 if(x) *x = xx; if(y) *y = yy;
966 #endif
967 }
968
969 void wxWindowX11::DoGetPosition(int *x, int *y) const
970 {
971 // TODO
972 #if 0
973 if (m_drawingArea)
974 {
975 CanvasGetPosition(x, y);
976 return;
977 }
978 Widget widget = (Widget) GetTopWidget();
979 Position xx, yy;
980 XtVaGetValues(widget, XmNx, &xx, XmNy, &yy, NULL);
981
982 // We may be faking the client origin. So a window that's really at (0, 30)
983 // may appear (to wxWin apps) to be at (0, 0).
984 if (GetParent())
985 {
986 wxPoint pt(GetParent()->GetClientAreaOrigin());
987 xx -= pt.x;
988 yy -= pt.y;
989 }
990
991 if(x) *x = xx; if(y) *y = yy;
992 #endif
993 }
994
995 void wxWindowX11::DoScreenToClient(int *x, int *y) const
996 {
997 Display *display = wxGetDisplay();
998 Window rootWindow = RootWindowOfScreen(DefaultScreenOfDisplay(display));
999 Window thisWindow = (Window) GetClientWindow();
1000
1001 Window childWindow;
1002 int xx = *x;
1003 int yy = *y;
1004 XTranslateCoordinates(display, rootWindow, thisWindow, xx, yy, x, y, &childWindow);
1005 }
1006
1007 void wxWindowX11::DoClientToScreen(int *x, int *y) const
1008 {
1009 Display *display = wxGetDisplay();
1010 Window rootWindow = RootWindowOfScreen(DefaultScreenOfDisplay(display));
1011 Window thisWindow = (Window) GetClientWindow();
1012
1013 Window childWindow;
1014 int xx = *x;
1015 int yy = *y;
1016 XTranslateCoordinates(display, thisWindow, rootWindow, xx, yy, x, y, &childWindow);
1017 }
1018
1019
1020 // Get size *available for subwindows* i.e. excluding menu bar etc.
1021 void wxWindowX11::DoGetClientSize(int *x, int *y) const
1022 {
1023 // TODO
1024 #if 0
1025 Widget widget = (Widget) GetClientWidget();
1026 Dimension xx, yy;
1027 XtVaGetValues(widget, XmNwidth, &xx, XmNheight, &yy, NULL);
1028 if(x) *x = xx; if(y) *y = yy;
1029 #endif
1030 }
1031
1032 void wxWindowX11::DoSetSize(int x, int y, int width, int height, int sizeFlags)
1033 {
1034 // TODO
1035 #if 0
1036 // A bit of optimization to help sort out the flickers.
1037 int oldX, oldY, oldW, oldH;
1038 GetSize(& oldW, & oldH);
1039 GetPosition(& oldX, & oldY);
1040
1041 if ( !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
1042 {
1043 if ( x == -1 )
1044 x = oldX;
1045 if ( y == -1 )
1046 y = oldY;
1047 }
1048
1049 if ( width == -1 )
1050 width = oldW;
1051 if ( height == -1 )
1052 height = oldH;
1053
1054 bool nothingChanged = (x == oldX) && (y == oldY) &&
1055 (width == oldW) && (height == oldH);
1056
1057 if (!wxNoOptimize::CanOptimize())
1058 {
1059 nothingChanged = FALSE;
1060 }
1061
1062 if ( !nothingChanged )
1063 {
1064 if (m_drawingArea)
1065 {
1066 CanvasSetSize(x, y, width, height, sizeFlags);
1067 return;
1068 }
1069
1070 Widget widget = (Widget) GetTopWidget();
1071 if (!widget)
1072 return;
1073
1074 bool managed = XtIsManaged( widget );
1075 if (managed)
1076 XtUnmanageChild(widget);
1077
1078 int xx = x;
1079 int yy = y;
1080 AdjustForParentClientOrigin(xx, yy, sizeFlags);
1081
1082 DoMoveWindow(xx, yy, width, height);
1083
1084 if (managed)
1085 XtManageChild(widget);
1086
1087 }
1088 #endif
1089 }
1090
1091 void wxWindowX11::DoSetClientSize(int width, int height)
1092 {
1093 // TODO
1094 #if 0
1095 if (m_drawingArea)
1096 {
1097 CanvasSetClientSize(width, height);
1098 return;
1099 }
1100
1101 Widget widget = (Widget) GetTopWidget();
1102
1103 if (width > -1)
1104 XtVaSetValues(widget, XmNwidth, width, NULL);
1105 if (height > -1)
1106 XtVaSetValues(widget, XmNheight, height, NULL);
1107
1108 wxSizeEvent sizeEvent(wxSize(width, height), GetId());
1109 sizeEvent.SetEventObject(this);
1110
1111 GetEventHandler()->ProcessEvent(sizeEvent);
1112 #endif
1113 }
1114
1115 // For implementation purposes - sometimes decorations make the client area
1116 // smaller
1117 wxPoint wxWindowX11::GetClientAreaOrigin() const
1118 {
1119 return wxPoint(0, 0);
1120 }
1121
1122 // Makes an adjustment to the window position (for example, a frame that has
1123 // a toolbar that it manages itself).
1124 void wxWindowX11::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags)
1125 {
1126 if (((sizeFlags & wxSIZE_NO_ADJUSTMENTS) == 0) && GetParent())
1127 {
1128 wxPoint pt(GetParent()->GetClientAreaOrigin());
1129 x += pt.x; y += pt.y;
1130 }
1131 }
1132
1133 void wxWindowX11::SetSizeHints(int minW, int minH, int maxW, int maxH, int incW, int incH)
1134 {
1135 // TODO
1136 #if 0
1137 m_minWidth = minW;
1138 m_minHeight = minH;
1139 m_maxWidth = maxW;
1140 m_maxHeight = maxH;
1141
1142 wxFrame *frame = wxDynamicCast(this, wxFrame);
1143 if ( !frame )
1144 {
1145 // TODO what about dialogs?
1146 return;
1147 }
1148
1149 Widget widget = (Widget) frame->GetShellWidget();
1150
1151 if (minW > -1)
1152 XtVaSetValues(widget, XmNminWidth, minW, NULL);
1153 if (minH > -1)
1154 XtVaSetValues(widget, XmNminHeight, minH, NULL);
1155 if (maxW > -1)
1156 XtVaSetValues(widget, XmNmaxWidth, maxW, NULL);
1157 if (maxH > -1)
1158 XtVaSetValues(widget, XmNmaxHeight, maxH, NULL);
1159 if (incW > -1)
1160 XtVaSetValues(widget, XmNwidthInc, incW, NULL);
1161 if (incH > -1)
1162 XtVaSetValues(widget, XmNheightInc, incH, NULL);
1163 #endif
1164 }
1165
1166 void wxWindowX11::DoMoveWindow(int x, int y, int width, int height)
1167 {
1168 // TODO
1169 #if 0
1170 XtVaSetValues((Widget)GetTopWidget(),
1171 XmNx, x,
1172 XmNy, y,
1173 XmNwidth, width,
1174 XmNheight, height,
1175 NULL);
1176 #endif
1177 }
1178
1179 // ---------------------------------------------------------------------------
1180 // text metrics
1181 // ---------------------------------------------------------------------------
1182
1183 int wxWindowX11::GetCharHeight() const
1184 {
1185 wxCHECK_MSG( m_font.Ok(), 0, "valid window font needed" );
1186
1187 WXFontStructPtr pFontStruct = m_font.GetFontStruct(1.0, GetXDisplay());
1188
1189 int direction, ascent, descent;
1190 XCharStruct overall;
1191 XTextExtents ((XFontStruct*) pFontStruct, "x", 1, &direction, &ascent,
1192 &descent, &overall);
1193
1194 // return (overall.ascent + overall.descent);
1195 return (ascent + descent);
1196 }
1197
1198 int wxWindowX11::GetCharWidth() const
1199 {
1200 wxCHECK_MSG( m_font.Ok(), 0, "valid window font needed" );
1201
1202 WXFontStructPtr pFontStruct = m_font.GetFontStruct(1.0, GetXDisplay());
1203
1204 int direction, ascent, descent;
1205 XCharStruct overall;
1206 XTextExtents ((XFontStruct*) pFontStruct, "x", 1, &direction, &ascent,
1207 &descent, &overall);
1208
1209 return overall.width;
1210 }
1211
1212 void wxWindowX11::GetTextExtent(const wxString& string,
1213 int *x, int *y,
1214 int *descent, int *externalLeading,
1215 const wxFont *theFont) const
1216 {
1217 wxFont *fontToUse = (wxFont *)theFont;
1218 if (!fontToUse)
1219 fontToUse = (wxFont *) & m_font;
1220
1221 wxCHECK_RET( fontToUse->Ok(), "valid window font needed" );
1222
1223 WXFontStructPtr pFontStruct = theFont->GetFontStruct(1.0, GetXDisplay());
1224
1225 int direction, ascent, descent2;
1226 XCharStruct overall;
1227 int slen = string.Len();
1228
1229 #if 0
1230 if (use16)
1231 XTextExtents16((XFontStruct*) pFontStruct, (XChar2b *) (char*) (const char*) string, slen, &direction,
1232 &ascent, &descent2, &overall);
1233 #endif
1234
1235 XTextExtents((XFontStruct*) pFontStruct, string, slen,
1236 &direction, &ascent, &descent2, &overall);
1237
1238 if ( x )
1239 *x = (overall.width);
1240 if ( y )
1241 *y = (ascent + descent2);
1242 if (descent)
1243 *descent = descent2;
1244 if (externalLeading)
1245 *externalLeading = 0;
1246
1247 }
1248
1249 // ----------------------------------------------------------------------------
1250 // painting
1251 // ----------------------------------------------------------------------------
1252
1253 void wxWindowX11::Refresh(bool eraseBack, const wxRect *rect)
1254 {
1255 m_needsRefresh = TRUE;
1256 Display *display = wxGetDisplay();
1257 Window thisWindow = (Widget) GetMainWindow();
1258
1259 XExposeEvent dummyEvent;
1260 int width, height;
1261 GetSize(&width, &height);
1262
1263 dummyEvent.type = Expose;
1264 dummyEvent.display = display;
1265 dummyEvent.send_event = True;
1266 dummyEvent.window = thisWindow;
1267 if (rect)
1268 {
1269 dummyEvent.x = rect->x;
1270 dummyEvent.y = rect->y;
1271 dummyEvent.width = rect->width;
1272 dummyEvent.height = rect->height;
1273 }
1274 else
1275 {
1276 dummyEvent.x = 0;
1277 dummyEvent.y = 0;
1278 dummyEvent.width = width;
1279 dummyEvent.height = height;
1280 }
1281 dummyEvent.count = 0;
1282
1283 if (eraseBack)
1284 {
1285 wxClientDC dc(this);
1286 wxBrush backgroundBrush(GetBackgroundColour(), wxSOLID);
1287 dc.SetBackground(backgroundBrush);
1288 if (rect)
1289 dc.Clear(*rect);
1290 else
1291 dc.Clear();
1292 }
1293
1294 XSendEvent(display, thisWindow, False, ExposureMask, (XEvent *)&dummyEvent);
1295 }
1296
1297 void wxWindowX11::Clear()
1298 {
1299 wxClientDC dc(this);
1300 wxBrush brush(GetBackgroundColour(), wxSOLID);
1301 dc.SetBackground(brush);
1302 dc.Clear();
1303 }
1304
1305 void wxWindowX11::ClearUpdateRects()
1306 {
1307 wxRectList::Node* node = m_updateRects.GetFirst();
1308 while (node)
1309 {
1310 wxRect* rect = node->GetData();
1311 delete rect;
1312 node = node->GetNext();
1313 }
1314
1315 m_updateRects.Clear();
1316 }
1317
1318 void wxWindowX11::DoPaint()
1319 {
1320 // Set an erase event first
1321 wxEraseEvent eraseEvent(GetId());
1322 eraseEvent.SetEventObject(this);
1323 GetEventHandler()->ProcessEvent(eraseEvent);
1324
1325 wxPaintEvent event(GetId());
1326 event.SetEventObject(this);
1327 GetEventHandler()->ProcessEvent(event);
1328
1329 m_needsRefresh = FALSE;
1330 }
1331
1332 // ----------------------------------------------------------------------------
1333 // event handlers
1334 // ----------------------------------------------------------------------------
1335
1336 // Responds to colour changes: passes event on to children.
1337 void wxWindowX11::OnSysColourChanged(wxSysColourChangedEvent& event)
1338 {
1339 wxWindowList::Node *node = GetChildren().GetFirst();
1340 while ( node )
1341 {
1342 // Only propagate to non-top-level windows
1343 wxWindow *win = node->GetData();
1344 if ( win->GetParent() )
1345 {
1346 wxSysColourChangedEvent event2;
1347 event.m_eventObject = win;
1348 win->GetEventHandler()->ProcessEvent(event2);
1349 }
1350
1351 node = node->GetNext();
1352 }
1353 }
1354
1355 void wxWindowX11::OnIdle(wxIdleEvent& WXUNUSED(event))
1356 {
1357 // This calls the UI-update mechanism (querying windows for
1358 // menu/toolbar/control state information)
1359 UpdateWindowUI();
1360 }
1361
1362 // ----------------------------------------------------------------------------
1363 // accelerators
1364 // ----------------------------------------------------------------------------
1365
1366 bool wxWindowX11::ProcessAccelerator(wxKeyEvent& event)
1367 {
1368 if (!m_acceleratorTable.Ok())
1369 return FALSE;
1370
1371 int count = m_acceleratorTable.GetCount();
1372 wxAcceleratorEntry* entries = m_acceleratorTable.GetEntries();
1373 int i;
1374 for (i = 0; i < count; i++)
1375 {
1376 wxAcceleratorEntry* entry = & (entries[i]);
1377 if (entry->MatchesEvent(event))
1378 {
1379 // Bingo, we have a match. Now find a control that matches the
1380 // entry command id.
1381
1382 // Need to go up to the top of the window hierarchy, since it might
1383 // be e.g. a menu item
1384 wxWindow* parent = this;
1385 while ( parent && !parent->IsTopLevel() )
1386 parent = parent->GetParent();
1387
1388 if (!parent)
1389 return FALSE;
1390
1391 wxFrame* frame = wxDynamicCast(parent, wxFrame);
1392 if ( frame )
1393 {
1394 // Try for a menu command
1395 if (frame->GetMenuBar())
1396 {
1397 wxMenuItem* item = frame->GetMenuBar()->FindItem(entry->GetCommand());
1398 if (item)
1399 {
1400 wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, entry->GetCommand());
1401 commandEvent.SetEventObject(frame);
1402
1403 // If ProcessEvent returns TRUE (it was handled), then
1404 // the calling code will skip the event handling.
1405 return frame->GetEventHandler()->ProcessEvent(commandEvent);
1406 }
1407 }
1408 }
1409
1410 // Find a child matching the command id
1411 wxWindow* child = parent->FindWindow(entry->GetCommand());
1412
1413 // No such child
1414 if (!child)
1415 return FALSE;
1416
1417 // Now we process those kinds of windows that we can.
1418 // For now, only buttons.
1419 if ( wxDynamicCast(child, wxButton) )
1420 {
1421 wxCommandEvent commandEvent (wxEVT_COMMAND_BUTTON_CLICKED, child->GetId());
1422 commandEvent.SetEventObject(child);
1423 return child->GetEventHandler()->ProcessEvent(commandEvent);
1424 }
1425
1426 return FALSE;
1427 } // matches event
1428 }// for
1429
1430 // We didn't match the key event against an accelerator.
1431 return FALSE;
1432 }
1433
1434 // ============================================================================
1435 // X11-specific stuff from here on
1436 // ============================================================================
1437
1438 // ----------------------------------------------------------------------------
1439 // function which maintain the global hash table mapping Widgets to wxWindows
1440 // ----------------------------------------------------------------------------
1441
1442 bool wxAddWindowToTable(Window w, wxWindow *win)
1443 {
1444 wxWindow *oldItem = NULL;
1445 if ((oldItem = (wxWindow *)wxWidgetHashTable->Get ((long) w)))
1446 {
1447 wxLogDebug("Widget table clash: new widget is %ld, %s",
1448 (long)w, win->GetClassInfo()->GetClassName());
1449 return FALSE;
1450 }
1451
1452 wxWidgetHashTable->Put((long) w, win);
1453
1454 wxLogTrace("widget", "XWindow 0x%08x <-> window %p (%s)",
1455 w, win, win->GetClassInfo()->GetClassName());
1456
1457 return TRUE;
1458 }
1459
1460 wxWindow *wxGetWindowFromTable(Window w)
1461 {
1462 return (wxWindow *)wxWidgetHashTable->Get((long) w);
1463 }
1464
1465 void wxDeleteWindowFromTable(Window w)
1466 {
1467 wxWidgetHashTable->Delete((long)w);
1468 }
1469
1470 // ----------------------------------------------------------------------------
1471 // add/remove window from the table
1472 // ----------------------------------------------------------------------------
1473
1474 // Add to hash table, add event handler
1475 bool wxWindowX11::AttachWidget (wxWindow* WXUNUSED(parent), WXWindow mainWidget,
1476 int x, int y, int width, int height)
1477 {
1478 wxAddWindowToTable((Window ) mainWidget, this);
1479
1480 // TODO
1481 #if 0
1482 if (CanAddEventHandler())
1483 {
1484 XtAddEventHandler((Widget) mainWidget,
1485 ButtonPressMask | ButtonReleaseMask | PointerMotionMask, // | KeyPressMask,
1486 False,
1487 wxPanelItemEventHandler,
1488 (XtPointer) this);
1489 }
1490
1491 if (!formWidget)
1492 {
1493 XtTranslations ptr;
1494 XtOverrideTranslations ((Widget) mainWidget,
1495 ptr = XtParseTranslationTable ("<Configure>: resize()"));
1496 XtFree ((char *) ptr);
1497 }
1498
1499 // Some widgets have a parent form widget, e.g. wxRadioBox
1500 if (formWidget)
1501 {
1502 if (!wxAddWindowToTable((Widget) formWidget, this))
1503 return FALSE;
1504
1505 XtTranslations ptr;
1506 XtOverrideTranslations ((Widget) formWidget,
1507 ptr = XtParseTranslationTable ("<Configure>: resize()"));
1508 XtFree ((char *) ptr);
1509 }
1510 #endif
1511 if (x == -1)
1512 x = 0;
1513 if (y == -1)
1514 y = 0;
1515
1516 SetSize (x, y, width, height);
1517
1518 return TRUE;
1519 }
1520
1521 // Remove event handler, remove from hash table
1522 bool wxWindowX11::DetachWidget(WXWindow widget)
1523 {
1524 // TODO
1525 #if 0
1526 if (CanAddEventHandler())
1527 {
1528 XtRemoveEventHandler((Widget) widget,
1529 ButtonPressMask | ButtonReleaseMask | PointerMotionMask, // | KeyPressMask,
1530 False,
1531 wxPanelItemEventHandler,
1532 (XtPointer)this);
1533 }
1534 #endif
1535
1536 wxDeleteWindowFromTable((Window) widget);
1537 return TRUE;
1538 }
1539
1540 // ----------------------------------------------------------------------------
1541 // X11-specific accessors
1542 // ----------------------------------------------------------------------------
1543
1544 // Get the underlying X window
1545 WXWindow wxWindowX11::GetXWindow() const
1546 {
1547 return GetMainWindow();
1548 }
1549
1550 // Get the underlying X display
1551 WXDisplay *wxWindowX11::GetXDisplay() const
1552 {
1553 return wxGetDisplay();
1554 }
1555
1556 WXWindow wxWindowX11::GetMainWindow() const
1557 {
1558 if (m_drawingArea)
1559 return m_drawingArea;
1560 else
1561 return m_mainWidget;
1562 }
1563
1564 WXWindow wxWindowX11::GetClientWidget() const
1565 {
1566 if (m_drawingArea != (WXWindow) 0)
1567 return m_drawingArea;
1568 else
1569 return GetMainWindow();
1570 }
1571
1572 WXWindow wxWindowX11::GetTopWindow() const
1573 {
1574 return GetMainWindow();
1575 }
1576
1577 WXWindow wxWindowX11::GetLabelWindow() const
1578 {
1579 return GetMainWindow();
1580 }
1581
1582 // ----------------------------------------------------------------------------
1583 // callbacks
1584 // ----------------------------------------------------------------------------
1585
1586 // TODO
1587 #if 0
1588
1589 // All widgets should have this as their resize proc.
1590 // OnSize sent to wxWindow via client data.
1591 void wxWidgetResizeProc(Widget w, XConfigureEvent *WXUNUSED(event), String WXUNUSED(args)[], int *WXUNUSED(num_args))
1592 {
1593 wxWindow *win = wxGetWindowFromTable(w);
1594 if (!win)
1595 return;
1596
1597 if (win->PreResize())
1598 {
1599 int width, height;
1600 win->GetSize(&width, &height);
1601 wxSizeEvent sizeEvent(wxSize(width, height), win->GetId());
1602 sizeEvent.SetEventObject(win);
1603 win->GetEventHandler()->ProcessEvent(sizeEvent);
1604 }
1605 }
1606
1607 static void wxCanvasRepaintProc(Widget drawingArea,
1608 XtPointer clientData,
1609 XmDrawingAreaCallbackStruct * cbs)
1610 {
1611 if (!wxGetWindowFromTable(drawingArea))
1612 return;
1613
1614 XEvent * event = cbs->event;
1615 wxWindow * win = (wxWindow *) clientData;
1616
1617 switch (event->type)
1618 {
1619 case Expose:
1620 {
1621 win->AddUpdateRect(event->xexpose.x, event->xexpose.y,
1622 event->xexpose.width, event->xexpose.height);
1623
1624 if (event -> xexpose.count == 0)
1625 {
1626 win->DoPaint();
1627 win->ClearUpdateRects();
1628 }
1629 break;
1630 }
1631 }
1632 }
1633
1634 // Unable to deal with Enter/Leave without a separate EventHandler (Motif 1.1.4)
1635 static void wxCanvasEnterLeave(Widget drawingArea,
1636 XtPointer WXUNUSED(clientData),
1637 XCrossingEvent * event)
1638 {
1639 XmDrawingAreaCallbackStruct cbs;
1640 XEvent ev;
1641
1642 ((XCrossingEvent &) ev) = *event;
1643
1644 cbs.reason = XmCR_INPUT;
1645 cbs.event = &ev;
1646
1647 wxCanvasInputEvent(drawingArea, (XtPointer) NULL, &cbs);
1648 }
1649
1650 // Fix to make it work under Motif 1.0 (!)
1651 static void wxCanvasMotionEvent (Widget WXUNUSED(drawingArea), XButtonEvent * WXUNUSED(event))
1652 {
1653 #if XmVersion <= 1000
1654 XmDrawingAreaCallbackStruct cbs;
1655 XEvent ev;
1656
1657 ev = *((XEvent *) event);
1658 cbs.reason = XmCR_INPUT;
1659 cbs.event = &ev;
1660
1661 wxCanvasInputEvent (drawingArea, (XtPointer) NULL, &cbs);
1662 #endif // XmVersion <= 1000
1663 }
1664
1665 static void wxCanvasInputEvent(Widget drawingArea,
1666 XtPointer WXUNUSED(data),
1667 XmDrawingAreaCallbackStruct * cbs)
1668 {
1669 wxWindow *canvas = wxGetWindowFromTable(drawingArea);
1670 XEvent local_event;
1671
1672 if (canvas==NULL)
1673 return;
1674
1675 if (cbs->reason != XmCR_INPUT)
1676 return;
1677
1678 local_event = *(cbs->event); // We must keep a copy!
1679
1680 switch (local_event.xany.type)
1681 {
1682 case EnterNotify:
1683 case LeaveNotify:
1684 case ButtonPress:
1685 case ButtonRelease:
1686 case MotionNotify:
1687 {
1688 // FIXME: most of this mouse event code is more or less
1689 // duplicated in wxTranslateMouseEvent
1690 //
1691 wxEventType eventType = wxEVT_NULL;
1692
1693 if (local_event.xany.type == EnterNotify)
1694 {
1695 //if (local_event.xcrossing.mode!=NotifyNormal)
1696 // return ; // Ignore grab events
1697 eventType = wxEVT_ENTER_WINDOW;
1698 // canvas->GetEventHandler()->OnSetFocus();
1699 }
1700 else if (local_event.xany.type == LeaveNotify)
1701 {
1702 //if (local_event.xcrossingr.mode!=NotifyNormal)
1703 // return ; // Ignore grab events
1704 eventType = wxEVT_LEAVE_WINDOW;
1705 // canvas->GetEventHandler()->OnKillFocus();
1706 }
1707 else if (local_event.xany.type == MotionNotify)
1708 {
1709 eventType = wxEVT_MOTION;
1710 }
1711
1712 else if (local_event.xany.type == ButtonPress)
1713 {
1714 if (local_event.xbutton.button == Button1)
1715 {
1716 eventType = wxEVT_LEFT_DOWN;
1717 canvas->SetButton1(TRUE);
1718 }
1719 else if (local_event.xbutton.button == Button2)
1720 {
1721 eventType = wxEVT_MIDDLE_DOWN;
1722 canvas->SetButton2(TRUE);
1723 }
1724 else if (local_event.xbutton.button == Button3)
1725 {
1726 eventType = wxEVT_RIGHT_DOWN;
1727 canvas->SetButton3(TRUE);
1728 }
1729 }
1730 else if (local_event.xany.type == ButtonRelease)
1731 {
1732 if (local_event.xbutton.button == Button1)
1733 {
1734 eventType = wxEVT_LEFT_UP;
1735 canvas->SetButton1(FALSE);
1736 }
1737 else if (local_event.xbutton.button == Button2)
1738 {
1739 eventType = wxEVT_MIDDLE_UP;
1740 canvas->SetButton2(FALSE);
1741 }
1742 else if (local_event.xbutton.button == Button3)
1743 {
1744 eventType = wxEVT_RIGHT_UP;
1745 canvas->SetButton3(FALSE);
1746 }
1747 }
1748
1749 wxMouseEvent wxevent (eventType);
1750
1751 wxevent.m_leftDown = ((eventType == wxEVT_LEFT_DOWN)
1752 || (event_left_is_down (&local_event)
1753 && (eventType != wxEVT_LEFT_UP)));
1754 wxevent.m_middleDown = ((eventType == wxEVT_MIDDLE_DOWN)
1755 || (event_middle_is_down (&local_event)
1756 && (eventType != wxEVT_MIDDLE_UP)));
1757 wxevent.m_rightDown = ((eventType == wxEVT_RIGHT_DOWN)
1758 || (event_right_is_down (&local_event)
1759 && (eventType != wxEVT_RIGHT_UP)));
1760
1761 wxevent.m_shiftDown = local_event.xbutton.state & ShiftMask;
1762 wxevent.m_controlDown = local_event.xbutton.state & ControlMask;
1763 wxevent.m_altDown = local_event.xbutton.state & Mod3Mask;
1764 wxevent.m_metaDown = local_event.xbutton.state & Mod1Mask;
1765 wxevent.SetTimestamp(local_event.xbutton.time);
1766
1767 if ( eventType == wxEVT_MOTION )
1768 {
1769 if (local_event.xmotion.is_hint == NotifyHint)
1770 {
1771 Window root, child;
1772 Display *dpy = XtDisplay (drawingArea);
1773
1774 XQueryPointer (dpy, XtWindow (drawingArea),
1775 &root, &child,
1776 &local_event.xmotion.x_root,
1777 &local_event.xmotion.y_root,
1778 &local_event.xmotion.x,
1779 &local_event.xmotion.y,
1780 &local_event.xmotion.state);
1781 }
1782 else
1783 {
1784 }
1785 }
1786
1787 // Now check if we need to translate this event into a double click
1788 if (TRUE) // canvas->doubleClickAllowed)
1789 {
1790 if (wxevent.ButtonDown())
1791 {
1792 long dclickTime = XtGetMultiClickTime((Display*) wxGetDisplay());
1793
1794 // get button and time-stamp
1795 int button = 0;
1796 if (wxevent.LeftDown())
1797 button = 1;
1798 else if (wxevent.MiddleDown())
1799 button = 2;
1800 else if (wxevent.RightDown())
1801 button = 3;
1802 long ts = wxevent.GetTimestamp();
1803
1804 // check, if single or double click
1805 int buttonLast = canvas->GetLastClickedButton();
1806 long lastTS = canvas->GetLastClickTime();
1807 if ( buttonLast && buttonLast == button && (ts - lastTS) < dclickTime )
1808 {
1809 // I have a dclick
1810 canvas->SetLastClick(0, ts);
1811
1812 wxEventType typeDouble;
1813 if ( eventType == wxEVT_LEFT_DOWN )
1814 typeDouble = wxEVT_LEFT_DCLICK;
1815 else if ( eventType == wxEVT_MIDDLE_DOWN )
1816 typeDouble = wxEVT_MIDDLE_DCLICK;
1817 else if ( eventType == wxEVT_RIGHT_DOWN )
1818 typeDouble = wxEVT_RIGHT_DCLICK;
1819 else
1820 typeDouble = wxEVT_NULL;
1821
1822 if ( typeDouble != wxEVT_NULL )
1823 {
1824 wxevent.SetEventType(typeDouble);
1825 }
1826 }
1827 else
1828 {
1829 // not fast enough or different button
1830 canvas->SetLastClick(button, ts);
1831 }
1832 }
1833 }
1834
1835 wxevent.SetId(canvas->GetId());
1836 wxevent.SetEventObject(canvas);
1837 wxevent.m_x = local_event.xbutton.x;
1838 wxevent.m_y = local_event.xbutton.y;
1839 canvas->GetEventHandler()->ProcessEvent (wxevent);
1840 #if 0
1841 if (eventType == wxEVT_ENTER_WINDOW ||
1842 eventType == wxEVT_LEAVE_WINDOW ||
1843 eventType == wxEVT_MOTION
1844 )
1845 return;
1846 #endif // 0
1847 break;
1848 }
1849 case KeyPress:
1850 {
1851 KeySym keySym;
1852 #if 0
1853 XComposeStatus compose;
1854 (void) XLookupString ((XKeyEvent *) & local_event, wxBuffer, 20, &keySym, &compose);
1855 #endif // 0
1856
1857 (void) XLookupString ((XKeyEvent *) & local_event, wxBuffer, 20, &keySym, NULL);
1858 int id = wxCharCodeXToWX (keySym);
1859
1860 wxEventType eventType = wxEVT_CHAR;
1861
1862 wxKeyEvent event (eventType);
1863
1864 if (local_event.xkey.state & ShiftMask)
1865 event.m_shiftDown = TRUE;
1866 if (local_event.xkey.state & ControlMask)
1867 event.m_controlDown = TRUE;
1868 if (local_event.xkey.state & Mod3Mask)
1869 event.m_altDown = TRUE;
1870 if (local_event.xkey.state & Mod1Mask)
1871 event.m_metaDown = TRUE;
1872 event.SetEventObject(canvas);
1873 event.m_keyCode = id;
1874 event.SetTimestamp(local_event.xkey.time);
1875
1876 if (id > -1)
1877 {
1878 // Implement wxFrame::OnCharHook by checking ancestor.
1879 wxWindow *parent = canvas->GetParent();
1880 while (parent && !parent->IsKindOf(CLASSINFO(wxFrame)))
1881 parent = parent->GetParent();
1882
1883 if (parent)
1884 {
1885 event.SetEventType(wxEVT_CHAR_HOOK);
1886 if (parent->GetEventHandler()->ProcessEvent(event))
1887 return;
1888 }
1889
1890 // For simplicity, OnKeyDown is the same as OnChar
1891 // TODO: filter modifier key presses from OnChar
1892 event.SetEventType(wxEVT_KEY_DOWN);
1893
1894 // Only process OnChar if OnKeyDown didn't swallow it
1895 if (!canvas->GetEventHandler()->ProcessEvent (event))
1896 {
1897 event.SetEventType(wxEVT_CHAR);
1898 canvas->GetEventHandler()->ProcessEvent (event);
1899 }
1900 }
1901 break;
1902 }
1903 case KeyRelease:
1904 {
1905 KeySym keySym;
1906 (void) XLookupString ((XKeyEvent *) & local_event, wxBuffer, 20, &keySym, NULL);
1907 int id = wxCharCodeXToWX (keySym);
1908
1909 wxKeyEvent event (wxEVT_KEY_UP);
1910
1911 if (local_event.xkey.state & ShiftMask)
1912 event.m_shiftDown = TRUE;
1913 if (local_event.xkey.state & ControlMask)
1914 event.m_controlDown = TRUE;
1915 if (local_event.xkey.state & Mod3Mask)
1916 event.m_altDown = TRUE;
1917 if (local_event.xkey.state & Mod1Mask)
1918 event.m_metaDown = TRUE;
1919 event.SetEventObject(canvas);
1920 event.m_keyCode = id;
1921 event.SetTimestamp(local_event.xkey.time);
1922
1923 if (id > -1)
1924 {
1925 canvas->GetEventHandler()->ProcessEvent (event);
1926 }
1927 break;
1928 }
1929 case FocusIn:
1930 {
1931 if (local_event.xfocus.detail != NotifyPointer)
1932 {
1933 wxFocusEvent event(wxEVT_SET_FOCUS, canvas->GetId());
1934 event.SetEventObject(canvas);
1935 canvas->GetEventHandler()->ProcessEvent(event);
1936 }
1937 break;
1938 }
1939 case FocusOut:
1940 {
1941 if (local_event.xfocus.detail != NotifyPointer)
1942 {
1943 wxFocusEvent event(wxEVT_KILL_FOCUS, canvas->GetId());
1944 event.SetEventObject(canvas);
1945 canvas->GetEventHandler()->ProcessEvent(event);
1946 }
1947 break;
1948 }
1949 default:
1950 break;
1951 }
1952 }
1953
1954 static void wxPanelItemEventHandler(Widget wid,
1955 XtPointer WXUNUSED(client_data),
1956 XEvent* event,
1957 Boolean *continueToDispatch)
1958 {
1959 // Widget can be a label or the actual widget.
1960
1961 wxWindow *window = wxGetWindowFromTable(wid);
1962 if (window)
1963 {
1964 wxMouseEvent wxevent(0);
1965 if (wxTranslateMouseEvent(wxevent, window, wid, event))
1966 {
1967 window->GetEventHandler()->ProcessEvent(wxevent);
1968 }
1969 }
1970
1971 // TODO: probably the key to allowing default behaviour to happen. Say we
1972 // set a m_doDefault flag to FALSE at the start of this function. Then in
1973 // e.g. wxWindowX11::OnMouseEvent we can call Default() which sets this flag to
1974 // TRUE, indicating that default processing can happen. Thus, behaviour can
1975 // appear to be overridden just by adding an event handler and not calling
1976 // wxWindowX11::OnWhatever. ALSO, maybe we can use this instead of the current
1977 // way of handling drawing area events, to simplify things.
1978 *continueToDispatch = True;
1979 }
1980
1981 static void wxScrollBarCallback(Widget scrollbar,
1982 XtPointer clientData,
1983 XmScrollBarCallbackStruct *cbs)
1984 {
1985 wxWindow *win = wxGetWindowFromTable(scrollbar);
1986 int orientation = (int) clientData;
1987
1988 wxEventType eventType = wxEVT_NULL;
1989 switch (cbs->reason)
1990 {
1991 case XmCR_INCREMENT:
1992 {
1993 eventType = wxEVT_SCROLLWIN_LINEDOWN;
1994 break;
1995 }
1996 case XmCR_DECREMENT:
1997 {
1998 eventType = wxEVT_SCROLLWIN_LINEUP;
1999 break;
2000 }
2001 case XmCR_DRAG:
2002 {
2003 eventType = wxEVT_SCROLLWIN_THUMBTRACK;
2004 break;
2005 }
2006 case XmCR_VALUE_CHANGED:
2007 {
2008 eventType = wxEVT_SCROLLWIN_THUMBRELEASE;
2009 break;
2010 }
2011 case XmCR_PAGE_INCREMENT:
2012 {
2013 eventType = wxEVT_SCROLLWIN_PAGEDOWN;
2014 break;
2015 }
2016 case XmCR_PAGE_DECREMENT:
2017 {
2018 eventType = wxEVT_SCROLLWIN_PAGEUP;
2019 break;
2020 }
2021 case XmCR_TO_TOP:
2022 {
2023 eventType = wxEVT_SCROLLWIN_TOP;
2024 break;
2025 }
2026 case XmCR_TO_BOTTOM:
2027 {
2028 eventType = wxEVT_SCROLLWIN_BOTTOM;
2029 break;
2030 }
2031 default:
2032 {
2033 // Should never get here
2034 wxFAIL_MSG("Unknown scroll event.");
2035 break;
2036 }
2037 }
2038
2039 wxScrollWinEvent event(eventType,
2040 cbs->value,
2041 ((orientation == XmHORIZONTAL) ?
2042 wxHORIZONTAL : wxVERTICAL));
2043 event.SetEventObject( win );
2044 win->GetEventHandler()->ProcessEvent(event);
2045 }
2046
2047 // For repainting arbitrary windows
2048 void wxUniversalRepaintProc(Widget w, XtPointer WXUNUSED(c_data), XEvent *event, char *)
2049 {
2050 Window window;
2051 Display *display;
2052
2053 wxWindow* win = wxGetWindowFromTable(w);
2054 if (!win)
2055 return;
2056
2057 switch(event -> type)
2058 {
2059 case Expose:
2060 {
2061 window = (Window) win -> GetXWindow();
2062 display = (Display *) win -> GetXDisplay();
2063
2064 if (event -> xexpose.count == 0)
2065 {
2066 win->DoPaint();
2067
2068 win->ClearUpdateRects();
2069 }
2070 else
2071 {
2072 win->AddUpdateRect(event->xexpose.x, event->xexpose.y,
2073 event->xexpose.width, event->xexpose.height);
2074 }
2075
2076 break;
2077 }
2078 }
2079 }
2080
2081 #endif
2082 // 0
2083
2084 // ----------------------------------------------------------------------------
2085 // CanvaseXXXSize() functions
2086 // ----------------------------------------------------------------------------
2087
2088 // SetSize, but as per old wxCanvas (with drawing widget etc.)
2089 void wxWindowX11::CanvasSetSize (int x, int y, int w, int h, int sizeFlags)
2090 {
2091 // TODO
2092 #if 0
2093 // A bit of optimization to help sort out the flickers.
2094 int oldX, oldY, oldW, oldH;
2095 GetSize(& oldW, & oldH);
2096 GetPosition(& oldX, & oldY);
2097
2098 bool useOldPos = FALSE;
2099 bool useOldSize = FALSE;
2100
2101 if ((x == -1) && (x == -1) && ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0))
2102 useOldPos = TRUE;
2103 else if (x == oldX && y == oldY)
2104 useOldPos = TRUE;
2105
2106 if ((w == -1) && (h == -1))
2107 useOldSize = TRUE;
2108 else if (w == oldW && h == oldH)
2109 useOldSize = TRUE;
2110
2111 if (!wxNoOptimize::CanOptimize())
2112 {
2113 useOldSize = FALSE; useOldPos = FALSE;
2114 }
2115
2116 if (useOldPos && useOldSize)
2117 return;
2118
2119 Widget drawingArea = (Widget) m_drawingArea;
2120 bool managed = XtIsManaged(m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow);
2121
2122 if (managed)
2123 XtUnmanageChild (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow);
2124 XtVaSetValues(drawingArea, XmNresizePolicy, XmRESIZE_ANY, NULL);
2125
2126 int xx = x; int yy = y;
2127 AdjustForParentClientOrigin(xx, yy, sizeFlags);
2128
2129 if (!useOldPos)
2130 {
2131 if (x > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
2132 {
2133 XtVaSetValues (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow,
2134 XmNx, xx, NULL);
2135 }
2136
2137 if (y > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
2138 {
2139 XtVaSetValues (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow,
2140 XmNy, yy, NULL);
2141 }
2142 }
2143
2144 if (!useOldSize)
2145 {
2146
2147 if (w > -1)
2148 {
2149 if (m_borderWidget)
2150 {
2151 XtVaSetValues ((Widget) m_borderWidget, XmNwidth, w, NULL);
2152 short thick, margin;
2153 XtVaGetValues ((Widget) m_borderWidget,
2154 XmNshadowThickness, &thick,
2155 XmNmarginWidth, &margin,
2156 NULL);
2157 w -= 2 * (thick + margin);
2158 }
2159
2160 XtVaSetValues ((Widget) m_scrolledWindow, XmNwidth, w, NULL);
2161
2162 Dimension spacing;
2163 Widget sbar;
2164 XtVaGetValues ((Widget) m_scrolledWindow,
2165 XmNspacing, &spacing,
2166 XmNverticalScrollBar, &sbar,
2167 NULL);
2168 Dimension wsbar;
2169 if (sbar)
2170 XtVaGetValues (sbar, XmNwidth, &wsbar, NULL);
2171 else
2172 wsbar = 0;
2173
2174 w -= (spacing + wsbar);
2175
2176 #if 0
2177 XtVaSetValues(drawingArea, XmNwidth, w, NULL);
2178 #endif // 0
2179 }
2180 if (h > -1)
2181 {
2182 if (m_borderWidget)
2183 {
2184 XtVaSetValues ((Widget) m_borderWidget, XmNheight, h, NULL);
2185 short thick, margin;
2186 XtVaGetValues ((Widget) m_borderWidget,
2187 XmNshadowThickness, &thick,
2188 XmNmarginHeight, &margin,
2189 NULL);
2190 h -= 2 * (thick + margin);
2191 }
2192
2193 XtVaSetValues ((Widget) m_scrolledWindow, XmNheight, h, NULL);
2194
2195 Dimension spacing;
2196 Widget sbar;
2197 XtVaGetValues ((Widget) m_scrolledWindow,
2198 XmNspacing, &spacing,
2199 XmNhorizontalScrollBar, &sbar,
2200 NULL);
2201 Dimension wsbar;
2202 if (sbar)
2203 XtVaGetValues (sbar, XmNheight, &wsbar, NULL);
2204 else
2205 wsbar = 0;
2206
2207 h -= (spacing + wsbar);
2208
2209 #if 0
2210 XtVaSetValues(drawingArea, XmNheight, h, NULL);
2211 #endif // 0
2212 }
2213 }
2214
2215 if (managed)
2216 XtManageChild (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow);
2217 XtVaSetValues(drawingArea, XmNresizePolicy, XmRESIZE_NONE, NULL);
2218 #endif
2219 // 0
2220 }
2221
2222 void wxWindowX11::CanvasSetClientSize (int w, int h)
2223 {
2224 // TODO
2225 #if 0
2226 Widget drawingArea = (Widget) m_drawingArea;
2227
2228 XtVaSetValues(drawingArea, XmNresizePolicy, XmRESIZE_ANY, NULL);
2229
2230 if (w > -1)
2231 XtVaSetValues(drawingArea, XmNwidth, w, NULL);
2232 if (h > -1)
2233 XtVaSetValues(drawingArea, XmNheight, h, NULL);
2234
2235 XtVaSetValues(drawingArea, XmNresizePolicy, XmRESIZE_NONE, NULL);
2236 #endif // 0
2237 }
2238
2239 void wxWindowX11::CanvasGetClientSize (int *w, int *h) const
2240 {
2241 // TODO
2242 #if 0
2243 // Must return the same thing that was set via SetClientSize
2244 Dimension xx, yy;
2245 XtVaGetValues ((Widget) m_drawingArea, XmNwidth, &xx, XmNheight, &yy, NULL);
2246 *w = xx;
2247 *h = yy;
2248 #endif
2249 }
2250
2251 void wxWindowX11::CanvasGetSize (int *w, int *h) const
2252 {
2253 // TODO
2254 #if 0
2255 Dimension xx, yy;
2256 if ((Widget) m_borderWidget)
2257 XtVaGetValues ((Widget) m_borderWidget, XmNwidth, &xx, XmNheight, &yy, NULL);
2258 else if ((Widget) m_scrolledWindow)
2259 XtVaGetValues ((Widget) m_scrolledWindow, XmNwidth, &xx, XmNheight, &yy, NULL);
2260 else
2261 XtVaGetValues ((Widget) m_drawingArea, XmNwidth, &xx, XmNheight, &yy, NULL);
2262
2263 *w = xx;
2264 *h = yy;
2265 #endif
2266 }
2267
2268 void wxWindowX11::CanvasGetPosition (int *x, int *y) const
2269 {
2270 // TODO
2271 #if 0
2272 Position xx, yy;
2273 XtVaGetValues (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow, XmNx, &xx, XmNy, &yy, NULL);
2274
2275 // We may be faking the client origin.
2276 // So a window that's really at (0, 30) may appear
2277 // (to wxWin apps) to be at (0, 0).
2278 if (GetParent())
2279 {
2280 wxPoint pt(GetParent()->GetClientAreaOrigin());
2281 xx -= pt.x;
2282 yy -= pt.y;
2283 }
2284
2285 *x = xx;
2286 *y = yy;
2287 #endif
2288 }
2289
2290 // ----------------------------------------------------------------------------
2291 // TranslateXXXEvent() functions
2292 // ----------------------------------------------------------------------------
2293
2294 bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, Widget widget, XEvent *xevent)
2295 {
2296 // TODO
2297 #if 0
2298 switch (xevent->xany.type)
2299 {
2300 case EnterNotify: // never received here - yes ? MB
2301 case LeaveNotify: // never received here - yes ? MB
2302 case ButtonPress:
2303 case ButtonRelease:
2304 case MotionNotify:
2305 {
2306 wxEventType eventType = wxEVT_NULL;
2307
2308 // FIXME: this is never true I think - MB
2309 //
2310 if (xevent->xany.type == LeaveNotify)
2311 {
2312 win->SetButton1(FALSE);
2313 win->SetButton2(FALSE);
2314 win->SetButton3(FALSE);
2315 return FALSE;
2316 }
2317 else if (xevent->xany.type == MotionNotify)
2318 {
2319 eventType = wxEVT_MOTION;
2320 }
2321 else if (xevent->xany.type == ButtonPress)
2322 {
2323 wxevent.SetTimestamp(xevent->xbutton.time);
2324 int button = 0;
2325 if (xevent->xbutton.button == Button1)
2326 {
2327 eventType = wxEVT_LEFT_DOWN;
2328 win->SetButton1(TRUE);
2329 button = 1;
2330 }
2331 else if (xevent->xbutton.button == Button2)
2332 {
2333 eventType = wxEVT_MIDDLE_DOWN;
2334 win->SetButton2(TRUE);
2335 button = 2;
2336 }
2337 else if (xevent->xbutton.button == Button3)
2338 {
2339 eventType = wxEVT_RIGHT_DOWN;
2340 win->SetButton3(TRUE);
2341 button = 3;
2342 }
2343
2344 // check for a double click
2345 //
2346 long dclickTime = XtGetMultiClickTime((Display*) wxGetDisplay());
2347 long ts = wxevent.GetTimestamp();
2348
2349 int buttonLast = win->GetLastClickedButton();
2350 long lastTS = win->GetLastClickTime();
2351 if ( buttonLast && buttonLast == button && (ts - lastTS) < dclickTime )
2352 {
2353 // I have a dclick
2354 win->SetLastClick(0, ts);
2355 if ( eventType == wxEVT_LEFT_DOWN )
2356 eventType = wxEVT_LEFT_DCLICK;
2357 else if ( eventType == wxEVT_MIDDLE_DOWN )
2358 eventType = wxEVT_MIDDLE_DCLICK;
2359 else if ( eventType == wxEVT_RIGHT_DOWN )
2360 eventType = wxEVT_RIGHT_DCLICK;
2361 }
2362 else
2363 {
2364 // not fast enough or different button
2365 win->SetLastClick(button, ts);
2366 }
2367 }
2368 else if (xevent->xany.type == ButtonRelease)
2369 {
2370 if (xevent->xbutton.button == Button1)
2371 {
2372 eventType = wxEVT_LEFT_UP;
2373 win->SetButton1(FALSE);
2374 }
2375 else if (xevent->xbutton.button == Button2)
2376 {
2377 eventType = wxEVT_MIDDLE_UP;
2378 win->SetButton2(FALSE);
2379 }
2380 else if (xevent->xbutton.button == Button3)
2381 {
2382 eventType = wxEVT_RIGHT_UP;
2383 win->SetButton3(FALSE);
2384 }
2385 else return FALSE;
2386 }
2387 else
2388 {
2389 return FALSE;
2390 }
2391
2392 wxevent.SetEventType(eventType);
2393
2394 Position x1, y1;
2395 XtVaGetValues(widget, XmNx, &x1, XmNy, &y1, NULL);
2396
2397 int x2, y2;
2398 win->GetPosition(&x2, &y2);
2399
2400 // The button x/y must be translated to wxWindows
2401 // window space - the widget might be a label or button,
2402 // within a form.
2403 int dx = 0;
2404 int dy = 0;
2405 if (widget != (Widget)win->GetMainWidget())
2406 {
2407 dx = x1;
2408 dy = y1;
2409 }
2410
2411 wxevent.m_x = xevent->xbutton.x + dx;
2412 wxevent.m_y = xevent->xbutton.y + dy;
2413
2414 wxevent.m_leftDown = ((eventType == wxEVT_LEFT_DOWN)
2415 || (event_left_is_down (xevent)
2416 && (eventType != wxEVT_LEFT_UP)));
2417 wxevent.m_middleDown = ((eventType == wxEVT_MIDDLE_DOWN)
2418 || (event_middle_is_down (xevent)
2419 && (eventType != wxEVT_MIDDLE_UP)));
2420 wxevent.m_rightDown = ((eventType == wxEVT_RIGHT_DOWN)
2421 || (event_right_is_down (xevent)
2422 && (eventType != wxEVT_RIGHT_UP)));
2423
2424 wxevent.m_shiftDown = xevent->xbutton.state & ShiftMask;
2425 wxevent.m_controlDown = xevent->xbutton.state & ControlMask;
2426 wxevent.m_altDown = xevent->xbutton.state & Mod3Mask;
2427 wxevent.m_metaDown = xevent->xbutton.state & Mod1Mask;
2428
2429 wxevent.SetId(win->GetId());
2430 wxevent.SetEventObject(win);
2431
2432 return TRUE;
2433 }
2434 }
2435 #endif
2436 return FALSE;
2437 }
2438
2439 bool wxTranslateKeyEvent(wxKeyEvent& wxevent, wxWindow *win, Window WXUNUSED(win), XEvent *xevent)
2440 {
2441 switch (xevent->xany.type)
2442 {
2443 case KeyPress:
2444 case KeyRelease:
2445 {
2446 char buf[20];
2447
2448 KeySym keySym;
2449 (void) XLookupString ((XKeyEvent *) xevent, buf, 20, &keySym, NULL);
2450 int id = wxCharCodeXToWX (keySym);
2451
2452 if (xevent->xkey.state & ShiftMask)
2453 wxevent.m_shiftDown = TRUE;
2454 if (xevent->xkey.state & ControlMask)
2455 wxevent.m_controlDown = TRUE;
2456 if (xevent->xkey.state & Mod3Mask)
2457 wxevent.m_altDown = TRUE;
2458 if (xevent->xkey.state & Mod1Mask)
2459 wxevent.m_metaDown = TRUE;
2460 wxevent.SetEventObject(win);
2461 wxevent.m_keyCode = id;
2462 wxevent.SetTimestamp(xevent->xkey.time);
2463
2464 wxevent.m_x = xevent->xbutton.x;
2465 wxevent.m_y = xevent->xbutton.y;
2466
2467 if (id > -1)
2468 return TRUE;
2469 else
2470 return FALSE;
2471 break;
2472 }
2473 default:
2474 break;
2475 }
2476 return FALSE;
2477 }
2478
2479 // ----------------------------------------------------------------------------
2480 // Colour stuff
2481 // ----------------------------------------------------------------------------
2482
2483 #if 0
2484
2485 #define YAllocColor XAllocColor
2486 XColor g_itemColors[5];
2487 int wxComputeColours (Display *display, wxColour * back, wxColour * fore)
2488 {
2489 int result;
2490 static XmColorProc colorProc;
2491
2492 result = wxNO_COLORS;
2493
2494 if (back)
2495 {
2496 g_itemColors[0].red = (((long) back->Red ()) << 8);
2497 g_itemColors[0].green = (((long) back->Green ()) << 8);
2498 g_itemColors[0].blue = (((long) back->Blue ()) << 8);
2499 g_itemColors[0].flags = DoRed | DoGreen | DoBlue;
2500 if (colorProc == (XmColorProc) NULL)
2501 {
2502 // Get a ptr to the actual function
2503 colorProc = XmSetColorCalculation ((XmColorProc) NULL);
2504 // And set it back to motif.
2505 XmSetColorCalculation (colorProc);
2506 }
2507 (*colorProc) (&g_itemColors[wxBACK_INDEX],
2508 &g_itemColors[wxFORE_INDEX],
2509 &g_itemColors[wxSELE_INDEX],
2510 &g_itemColors[wxTOPS_INDEX],
2511 &g_itemColors[wxBOTS_INDEX]);
2512 result = wxBACK_COLORS;
2513 }
2514 if (fore)
2515 {
2516 g_itemColors[wxFORE_INDEX].red = (((long) fore->Red ()) << 8);
2517 g_itemColors[wxFORE_INDEX].green = (((long) fore->Green ()) << 8);
2518 g_itemColors[wxFORE_INDEX].blue = (((long) fore->Blue ()) << 8);
2519 g_itemColors[wxFORE_INDEX].flags = DoRed | DoGreen | DoBlue;
2520 if (result == wxNO_COLORS)
2521 result = wxFORE_COLORS;
2522 }
2523
2524 Display *dpy = display;
2525 Colormap cmap = (Colormap) wxTheApp->GetMainColormap((WXDisplay*) dpy);
2526
2527 if (back)
2528 {
2529 /* 5 Colours to allocate */
2530 for (int i = 0; i < 5; i++)
2531 if (!YAllocColor (dpy, cmap, &g_itemColors[i]))
2532 result = wxNO_COLORS;
2533 }
2534 else if (fore)
2535 {
2536 /* Only 1 colour to allocate */
2537 if (!YAllocColor (dpy, cmap, &g_itemColors[wxFORE_INDEX]))
2538 result = wxNO_COLORS;
2539 }
2540
2541 return (result);
2542
2543 }
2544 #endif
2545
2546 // Changes the foreground and background colours to be derived from the current
2547 // background colour. To change the foreground colour, you must call
2548 // SetForegroundColour explicitly.
2549 void wxWindowX11::ChangeBackgroundColour()
2550 {
2551 // TODO
2552 #if 0
2553 WXWidget mainWidget = GetMainWidget();
2554 if ( mainWidget )
2555 DoChangeBackgroundColour(mainWidget, m_backgroundColour);
2556 #endif
2557 }
2558
2559 void wxWindowX11::ChangeForegroundColour()
2560 {
2561 // TODO
2562 #if 0
2563 WXWidget mainWidget = GetMainWidget();
2564 if ( mainWidget )
2565 DoChangeForegroundColour(mainWidget, m_foregroundColour);
2566 if ( m_scrolledWindow && mainWidget != m_scrolledWindow )
2567 DoChangeForegroundColour(m_scrolledWindow, m_foregroundColour);
2568 #endif
2569 }
2570
2571 // Change a widget's foreground and background colours.
2572 void wxWindowX11::DoChangeForegroundColour(WXWindow widget, wxColour& foregroundColour)
2573 {
2574 // TODO
2575 #if 0
2576 // When should we specify the foreground, if it's calculated
2577 // by wxComputeColours?
2578 // Solution: say we start with the default (computed) foreground colour.
2579 // If we call SetForegroundColour explicitly for a control or window,
2580 // then the foreground is changed.
2581 // Therefore SetBackgroundColour computes the foreground colour, and
2582 // SetForegroundColour changes the foreground colour. The ordering is
2583 // important.
2584
2585 Widget w = (Widget)widget;
2586 XtVaSetValues(
2587 w,
2588 XmNforeground, foregroundColour.AllocColour(XtDisplay(w)),
2589 NULL
2590 );
2591 #endif
2592 }
2593
2594 void wxWindowX11::DoChangeBackgroundColour(WXWindow widget, wxColour& backgroundColour, bool changeArmColour)
2595 {
2596 // TODO
2597 #if 0
2598 wxComputeColours (XtDisplay((Widget) widget), & backgroundColour,
2599 (wxColour*) NULL);
2600
2601 XtVaSetValues ((Widget) widget,
2602 XmNbackground, g_itemColors[wxBACK_INDEX].pixel,
2603 XmNtopShadowColor, g_itemColors[wxTOPS_INDEX].pixel,
2604 XmNbottomShadowColor, g_itemColors[wxBOTS_INDEX].pixel,
2605 XmNforeground, g_itemColors[wxFORE_INDEX].pixel,
2606 NULL);
2607
2608 if (changeArmColour)
2609 XtVaSetValues ((Widget) widget,
2610 XmNarmColor, g_itemColors[wxSELE_INDEX].pixel,
2611 NULL);
2612 #endif
2613 }
2614
2615 bool wxWindowX11::SetBackgroundColour(const wxColour& col)
2616 {
2617 if ( !wxWindowBase::SetBackgroundColour(col) )
2618 return FALSE;
2619
2620 ChangeBackgroundColour();
2621
2622 return TRUE;
2623 }
2624
2625 bool wxWindowX11::SetForegroundColour(const wxColour& col)
2626 {
2627 if ( !wxWindowBase::SetForegroundColour(col) )
2628 return FALSE;
2629
2630 ChangeForegroundColour();
2631
2632 return TRUE;
2633 }
2634
2635 void wxWindowX11::ChangeFont(bool keepOriginalSize)
2636 {
2637 // TODO
2638 #if 0
2639 // Note that this causes the widget to be resized back
2640 // to its original size! We therefore have to set the size
2641 // back again. TODO: a better way in Motif?
2642 Widget w = (Widget) GetLabelWidget(); // Usually the main widget
2643 if (w && m_font.Ok())
2644 {
2645 int width, height, width1, height1;
2646 GetSize(& width, & height);
2647
2648 // lesstif 0.87 hangs here
2649 #ifndef LESSTIF_VERSION
2650 XtVaSetValues (w,
2651 XmNfontList, (XmFontList) m_font.GetFontList(1.0, XtDisplay(w)),
2652 NULL);
2653 #endif
2654
2655 GetSize(& width1, & height1);
2656 if (keepOriginalSize && (width != width1 || height != height1))
2657 {
2658 SetSize(-1, -1, width, height);
2659 }
2660 }
2661 #endif
2662 }
2663
2664 // ----------------------------------------------------------------------------
2665 // global functions
2666 // ----------------------------------------------------------------------------
2667
2668 wxWindow *wxGetActiveWindow()
2669 {
2670 // TODO
2671 wxFAIL_MSG("Not implemented");
2672 return NULL;
2673 }
2674
2675 /* static */
2676 wxWindow *wxWindowBase::GetCapture()
2677 {
2678 return (wxWindow *)g_captureWindow;
2679 }
2680
2681
2682 // Find the wxWindow at the current mouse position, returning the mouse
2683 // position.
2684 wxWindow* wxFindWindowAtPointer(wxPoint& pt)
2685 {
2686 return wxFindWindowAtPoint(wxGetMousePosition());
2687 }
2688
2689 // Get the current mouse position.
2690 wxPoint wxGetMousePosition()
2691 {
2692 Display *display = (Display*) wxGetDisplay();
2693 Window rootWindow = RootWindowOfScreen (DefaultScreenOfDisplay(display));
2694 Window rootReturn, childReturn;
2695 int rootX, rootY, winX, winY;
2696 unsigned int maskReturn;
2697
2698 XQueryPointer (display,
2699 rootWindow,
2700 &rootReturn,
2701 &childReturn,
2702 &rootX, &rootY, &winX, &winY, &maskReturn);
2703 return wxPoint(rootX, rootY);
2704 }
2705
2706
2707 // ----------------------------------------------------------------------------
2708 // wxNoOptimize: switch off size optimization
2709 // ----------------------------------------------------------------------------
2710
2711 int wxNoOptimize::ms_count = 0;
2712