In System.Windows.Forms:
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms.X11Internal / XplatUIX11-new.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 // 
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 // 
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2004-2006 Novell, Inc.
21 //
22 // Authors:
23 //      Peter Bartok    pbartok@novell.com
24 //      Chris Toshok    toshok@ximian.com
25 //
26 //
27
28 // NOTE:
29 //      This driver understands the following environment variables: (Set the var to enable feature)
30 //
31 //      MONO_XEXCEPTIONS        = throw an exception when a X11 error is encountered;
32 //                                by default a message is displayed but execution continues
33 //
34 //      MONO_XSYNC              = perform all X11 commands synchronous; this is slower but
35 //                                helps in debugging errors
36 //
37
38 // NOT COMPLETE
39
40 // define to log Window handles and relationships to stdout
41 #undef DriverDebug
42
43 // Extra detailed debug
44 #undef DriverDebugExtra
45 #undef DriverDebugParent
46 #undef DriverDebugCreate
47 #undef DriverDebugDestroy
48 #undef DriverDebugThreads
49 #undef DriverDebugXEmbed
50
51 using System;
52 using System.ComponentModel;
53 using System.Collections;
54 using System.Diagnostics;
55 using System.Drawing;
56 using System.Drawing.Drawing2D;
57 using System.Drawing.Imaging;
58 using System.IO;
59 using System.Net;
60 using System.Net.Sockets;
61 using System.Reflection;
62 using System.Runtime.InteropServices;
63 using System.Text;
64 using System.Threading;
65 using System.Windows.Forms;
66
67 /// X11 Version
68 namespace System.Windows.Forms.X11Internal {
69         internal class XplatUIX11_new : XplatUIDriver {
70                 #region Local Variables
71                 // General
72                 static volatile XplatUIX11_new Instance;
73                 static readonly object lockobj = new object ();
74                 static int RefCount;
75                 static bool themes_enabled;
76
77                 static Hashtable MessageQueues; // Holds our thread-specific X11ThreadQueues
78
79                 X11Display display;
80
81                 #endregion      // Local Variables
82                 #region Constructors
83                 private XplatUIX11_new() {
84                         // Handle singleton stuff first
85                         RefCount = 0;
86
87                         // Now regular initialization
88                         MessageQueues = Hashtable.Synchronized (new Hashtable(7));
89                         if (Xlib.XInitThreads() == 0) {
90                                 Console.WriteLine ("Failed XInitThreads.  The X11 event loop will not function properly");
91                         }
92                 }
93
94                 private void InitializeDisplay ()
95                 {
96                         display = new X11Display (Xlib.XOpenDisplay(IntPtr.Zero));
97
98                         Graphics.FromHdcInternal (display.Handle);
99                 }
100
101                 ~XplatUIX11_new() {
102                         // Remove our display handle from S.D
103                         Graphics.FromHdcInternal (IntPtr.Zero);
104                 }
105
106                 #endregion      // Constructors
107
108                 #region Singleton Specific Code
109                 public static XplatUIX11_new GetInstance() {
110                         lock (lockobj) {
111                                 if (Instance == null) {
112                                         Instance = new XplatUIX11_new ();
113
114                                         Instance.InitializeDisplay ();
115                                 }
116                                 RefCount++;
117                         }
118                         return Instance;
119                 }
120
121                 public int Reference {
122                         get {
123                                 return RefCount;
124                         }
125                 }
126                 #endregion
127
128                 #region Internal Methods
129                 internal static void Where() {
130                         Console.WriteLine("Here: {0}\n", GetInstance().display.WhereString());
131                 }
132
133                 #endregion      // Internal Methods
134
135                 #region Private Methods
136
137                 internal X11ThreadQueue ThreadQueue (Thread thread)
138                 {
139                         X11ThreadQueue  queue;
140
141                         queue = (X11ThreadQueue)MessageQueues[thread];
142                         if (queue == null) {
143                                 queue = new X11ThreadQueue(thread);
144                                 MessageQueues[thread] = queue;
145                         }
146
147                         return queue;
148                 }
149                 #endregion      // Private Methods
150
151
152                 #region Public Properties
153                 internal override int Caption {
154                         get { return 19; }
155                 }
156
157                 internal override Size CursorSize {
158                         get { return display.CursorSize; }
159                 }
160
161                 internal override bool DragFullWindows {
162                         get { return true; }
163                 } 
164
165                 internal override Size DragSize {
166                         get { return new Size(4, 4); }
167                 } 
168
169                 internal override Size FrameBorderSize { 
170                         get { throw new NotImplementedException(); }
171                 }
172
173                 internal override Size IconSize {
174                         get { return display.IconSize; }
175                 }
176
177                 internal override int KeyboardSpeed {
178                         get { return display.KeyboardSpeed; }
179                 }
180
181                 internal override int KeyboardDelay {
182                         get { return display.KeyboardSpeed; }
183                 }
184
185                 internal override Size MaxWindowTrackSize {
186                         get { return new Size (WorkingArea.Width, WorkingArea.Height); }
187                 } 
188
189                 internal override Size MinimizedWindowSize {
190                         get { return new Size(1, 1); }
191                 } 
192
193                 internal override Size MinimizedWindowSpacingSize {
194                         get { return new Size(1, 1); }
195                 } 
196
197                 internal override Size MinimumWindowSize {
198                         get { return new Size(1, 1); }
199                 } 
200
201                 internal override Size MinWindowTrackSize {
202                         get { return new Size(1, 1); }
203                 }
204
205                 internal override Keys ModifierKeys {
206                         get { return display.ModifierKeys; }
207                 }
208
209                 internal override Size SmallIconSize {
210                         get { return display.SmallIconSize; }
211                 }
212
213                 internal override int MouseButtonCount {
214                         get { return 3; /* FIXME - should detect this somehow.. */}
215                 } 
216
217                 internal override bool MouseButtonsSwapped {
218                         get { return false; /*FIXME - how to detect? */}
219                 } 
220
221                 internal override Size MouseHoverSize {
222                         get { return new Size (1, 1); }
223                 }
224
225                 internal override int MouseHoverTime {
226                         get { return display.MouseHoverTime; }
227                 }
228
229                 internal override bool MouseWheelPresent {
230                         get { return true; /* FIXME - how to detect? */ }
231                 } 
232
233                 internal override Rectangle VirtualScreen {
234                         get { return WorkingArea; }
235                 } 
236
237                 internal override Rectangle WorkingArea {
238                         get { return display.WorkingArea; }
239                 }
240
241                 internal override bool ThemesEnabled {
242                         get { return XplatUIX11_new.themes_enabled; }
243                 }
244  
245
246                 #endregion      // Public properties
247
248                 #region Public Static Methods
249                 internal override IntPtr InitializeDriver()
250                 {
251                         lock (this) {
252                                 if (display == null)
253                                         display = new X11Display (Xlib.XOpenDisplay(IntPtr.Zero));
254                         }
255                         return IntPtr.Zero;
256                 }
257
258                 internal override void ShutdownDriver(IntPtr token)
259                 {
260                         lock (this) {
261                                 if (display != null) {
262                                         display.Close ();
263                                         display = null;
264                                 }
265                         }
266                 }
267
268                 internal override void EnableThemes()
269                 {
270                         themes_enabled = true;
271                 }
272
273                 internal override void Activate (IntPtr handle)
274                 {
275                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
276
277                         if (hwnd != null)
278                                 hwnd.Activate ();
279                 }
280
281                 internal override void AudibleAlert()
282                 {
283                         display.AudibleAlert ();
284                 }
285
286
287                 internal override void CaretVisible (IntPtr handle, bool visible)
288                 {
289                         display.CaretVisible (handle, visible);
290                 }
291
292                 // XXX this implementation should probably be shared between all non-win32 backends
293                 internal override bool CalculateWindowRect (ref Rectangle ClientRect, int Style, int ExStyle, Menu menu, out Rectangle WindowRect)
294                 {
295                         FormBorderStyle border_style;
296                         TitleStyle      title_style;
297                         int caption_height;
298                         int tool_caption_height;
299
300                         // XXX this method should be static on Hwnd, not X11Hwnd
301                         X11Hwnd.DeriveStyles (Style, ExStyle, out border_style, out title_style,
302                                               out caption_height, out tool_caption_height);
303
304                         WindowRect = Hwnd.GetWindowRectangle(border_style, menu, title_style,
305                                                              caption_height, tool_caption_height,
306                                                              ClientRect);
307                         return true;
308                 }
309
310                 internal override void ClientToScreen (IntPtr handle, ref int x, ref int y)
311                 {
312                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
313
314                         if (hwnd != null)
315                                 hwnd.ClientToScreen (ref x, ref y);
316                 }
317
318                 internal override int[] ClipboardAvailableFormats (IntPtr handle)
319                 {
320                         return display.ClipboardAvailableFormats (handle);
321                 }
322
323                 internal override void ClipboardClose (IntPtr handle)
324                 {
325                         display.ClipboardClose (handle);
326                 }
327
328                 internal override int ClipboardGetID (IntPtr handle, string format)
329                 {
330                         return display.ClipboardGetID (handle, format);
331                 }
332
333                 internal override IntPtr ClipboardOpen (bool primary_selection)
334                 {
335                         return display.ClipboardOpen (primary_selection);
336                 }
337
338                 internal override object ClipboardRetrieve (IntPtr handle, int type, XplatUI.ClipboardToObject converter)
339                 {
340                         return display.ClipboardRetrieve (handle, type, converter);
341                 }
342
343                 internal override void ClipboardStore (IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter)
344                 {
345                         display.ClipboardStore (handle, obj, type, converter);
346                 }
347
348                 internal override void CreateCaret (IntPtr handle, int width, int height)
349                 {
350                         display.CreateCaret (handle, width, height);
351                 }
352
353                 internal override IntPtr CreateWindow (CreateParams cp)
354                 {
355                         X11Hwnd hwnd = new X11Hwnd (display);
356
357                         hwnd.CreateWindow (cp);
358
359                         return hwnd.Handle;
360                 }
361
362                 internal override IntPtr CreateWindow (IntPtr Parent, int X, int Y, int Width, int Height)
363                 {
364                         CreateParams create_params = new CreateParams();
365
366                         create_params.Caption = "";
367                         create_params.X = X;
368                         create_params.Y = Y;
369                         create_params.Width = Width;
370                         create_params.Height = Height;
371
372                         create_params.ClassName = XplatUI.DefaultClassName;
373                         create_params.ClassStyle = 0;
374                         create_params.ExStyle = 0;
375                         create_params.Parent = IntPtr.Zero;
376                         create_params.Param = 0;
377
378                         return CreateWindow (create_params);
379                 }
380
381                 internal override IntPtr DefineCursor (Bitmap bitmap, Bitmap mask, Color cursor_pixel, Color mask_pixel, int xHotSpot, int yHotSpot)
382                 {
383                         return display.DefineCursor (bitmap, mask, cursor_pixel, mask_pixel, xHotSpot, yHotSpot);
384                 }
385
386                 internal override IntPtr DefineStdCursor (StdCursor id)
387                 {
388                         return display.DefineStdCursor (id);
389                 }
390
391                 internal override IntPtr DefWndProc(ref Message msg)
392                 {
393                         X11Hwnd hwnd = (X11Hwnd)Hwnd.GetObjectFromWindow(msg.HWnd);
394
395                         if (hwnd == null)
396                                 return IntPtr.Zero;
397
398                         return hwnd.DefWndProc (ref msg);
399                 }
400
401                 internal override void DestroyCaret (IntPtr handle)
402                 {
403                         display.DestroyCaret (handle);
404                 }
405
406                 internal override void DestroyCursor(IntPtr cursor)
407                 {
408                         display.DestroyCursor (cursor);
409                 }
410
411                 internal override void DestroyWindow (IntPtr handle) {
412                         X11Hwnd hwnd;
413
414                         hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
415
416                         if (hwnd == null) {
417 #if DriverDebug || DriverDebugDestroy
418                                 Console.WriteLine("window {0:X} already destroyed", handle.ToInt32());
419 #endif
420                                 return;
421                         }
422
423 #if DriverDebug || DriverDebugDestroy
424                         Console.WriteLine("Destroying window {0}", XplatUI.Window(hwnd.ClientWindow));
425 #endif
426
427                         display.DestroyWindow (hwnd);
428                 }
429
430                 internal override IntPtr DispatchMessage(ref MSG msg)
431                 {
432                         return display.DispatchMessage (ref msg);
433                 }
434
435                 internal override void DrawReversibleRectangle (IntPtr handle, Rectangle rect, int line_width)
436                 {
437                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
438
439                         if (hwnd != null)
440                                 hwnd.DrawReversibleRectangle (rect, line_width);
441                 }
442
443                 internal override void DoEvents ()
444                 {
445                         X11ThreadQueue queue = ThreadQueue (Thread.CurrentThread);
446                         display.DoEvents (queue);
447                 }
448
449                 internal override void EnableWindow (IntPtr handle, bool Enable)
450                 {
451                         Hwnd    hwnd;
452
453                         hwnd = Hwnd.ObjectFromHandle(handle);
454                         if (hwnd != null)
455                                 hwnd.Enabled = Enable;
456                 }
457
458                 internal override void EndLoop (Thread thread)
459                 {
460                         // This is where we one day will shut down the loop for the thread
461                 }
462
463
464                 internal override IntPtr GetActive()
465                 {
466                         X11Hwnd hwnd = display.GetActiveWindow ();
467
468                         return (hwnd == null) ? IntPtr.Zero : hwnd.Handle;
469                 }
470
471                 internal override Region GetClipRegion (IntPtr handle)
472                 {
473                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
474
475                         return (hwnd == null) ? null : hwnd.GetClipRegion ();
476                 }
477
478                 internal override void GetCursorInfo(IntPtr cursor, out int width, out int height, out int hotspot_x, out int hotspot_y)
479                 {
480                         width = 20;
481                         height = 20;
482                         hotspot_x = 0;
483                         hotspot_y = 0;
484                 }
485
486                 internal override void GetDisplaySize(out Size size)
487                 {
488                         display.GetDisplaySize (out size);
489                 }
490
491                 internal override SizeF GetAutoScaleSize (Font font)
492                 {
493                         return display.GetAutoScaleSize (font);
494                 }
495
496                 // XXX this should be someplace shareable by all non-win32 backends..  like in Hwnd itself.
497                 // maybe a Hwnd.ParentHandle property
498                 internal override IntPtr GetParent (IntPtr handle)
499                 {
500                         Hwnd    hwnd;
501
502                         hwnd = Hwnd.ObjectFromHandle(handle);
503                         if (hwnd != null && hwnd.parent != null) {
504                                 return hwnd.parent.Handle;
505                         }
506                         return IntPtr.Zero;
507                 }
508
509                 internal override void GetCursorPos (IntPtr handle, out int x, out int y)
510                 {
511                         display.GetCursorPos ((X11Hwnd)Hwnd.ObjectFromHandle(handle),
512                                               out x, out y);
513                 }
514
515                 internal override IntPtr GetFocus()
516                 {
517                         return display.GetFocus ();
518                 }
519
520                 // XXX this should be shared amongst non-win32 backends
521                 internal override bool GetFontMetrics (Graphics g, Font font, out int ascent, out int descent)
522                 {
523                         return Xlib.GetFontMetrics(g.GetHdc(), font.ToHfont(), out ascent, out descent);
524                 }
525
526
527                 // XXX this should be shared amongst non-win32 backends
528                 internal override Point GetMenuOrigin (IntPtr handle)
529                 {
530                         Hwnd    hwnd;
531
532                         hwnd = Hwnd.ObjectFromHandle(handle);
533
534                         if (hwnd != null)
535                                 return hwnd.MenuOrigin;
536
537                         return Point.Empty;
538                 }
539
540                 internal override bool GetMessage (object queue_id, ref MSG msg, IntPtr handle, int wFilterMin, int wFilterMax)
541                 {
542                         return display.GetMessage (queue_id, ref msg, handle, wFilterMin, wFilterMax);
543                 }
544
545                 internal override bool GetText (IntPtr handle, out string text)
546                 {
547                         X11Hwnd hwnd = (X11Hwnd) Hwnd.ObjectFromHandle(handle);
548
549                         text = "";
550                         return hwnd != null && hwnd.GetText (out text);
551                 }
552
553                 internal override void GetWindowPos (IntPtr handle, bool is_toplevel,
554                                                      out int x, out int y,
555                                                      out int width, out int height,
556                                                      out int client_width, out int client_height)
557                 {
558                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
559
560                         if (hwnd != null) {
561                                 hwnd.GetPosition (is_toplevel, out x, out y, out width, out height, out client_width, out client_height);
562                         }
563                         else {
564                                 // Should we throw an exception or fail silently?
565                                 // throw new ArgumentException("Called with an invalid window handle", "handle");
566
567                                 x = 0;
568                                 y = 0;
569                                 width = 0;
570                                 height = 0;
571                                 client_width = 0;
572                                 client_height = 0;
573                         }
574                 }
575
576                 internal override FormWindowState GetWindowState (IntPtr handle)
577                 {
578                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
579
580                         if (hwnd == null)
581                                 return FormWindowState.Normal; // XXX should we throw an exception here?  probably
582
583                         return hwnd.GetWindowState ();
584                 }
585
586                 internal override void GrabInfo (out IntPtr handle, out bool GrabConfined, out Rectangle GrabArea)
587                 {
588                         display.GrabInfo (out handle, out GrabConfined, out GrabArea);
589                 }
590
591                 internal override void GrabWindow (IntPtr handle, IntPtr confine_to_handle)
592                 {
593                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
594                         X11Hwnd confine_to_hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(confine_to_handle);
595
596                         display.GrabWindow (hwnd, confine_to_hwnd);
597                 }
598
599                 internal override void UngrabWindow (IntPtr handle)
600                 {
601                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
602
603                         display.UngrabWindow (hwnd);
604                 }
605
606                 internal override void HandleException(Exception e) {
607                         StackTrace st = new StackTrace(e, true);
608                         Console.WriteLine("Exception '{0}'", e.Message+st.ToString());
609                         Console.WriteLine("{0}{1}", e.Message, st.ToString());
610                 }
611
612                 internal override void Invalidate (IntPtr handle, Rectangle rc, bool clear)
613                 {
614                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
615
616                         hwnd.Invalidate (rc, clear);
617                 }
618
619                 internal override void InvalidateNC (IntPtr handle)
620                 {
621                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
622
623                         hwnd.InvalidateNC ();
624                 }
625
626                 internal override bool IsEnabled(IntPtr handle)
627                 {
628                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle (handle);
629
630                         return hwnd != null && hwnd.Enabled;
631                 }
632                 
633                 internal override bool IsVisible(IntPtr handle)
634                 {
635                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle (handle);
636
637                         return hwnd != null && hwnd.Visible;
638                 }
639
640                 internal override void KillTimer (Timer timer)
641                 {
642                         X11ThreadQueue queue = (X11ThreadQueue) MessageQueues [timer.thread];
643
644                         if (queue == null) {
645                                 // This isn't really an error, MS doesn't start the timer if
646                                 // it has no assosciated queue
647                                 return;
648                         }
649                         queue.KillTimer (timer);
650                 }
651
652                 internal override void MenuToScreen (IntPtr handle, ref int x, ref int y)
653                 {
654                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
655
656                         if (hwnd != null)
657                                 hwnd.MenuToScreen (ref x, ref y);
658                 }
659
660                 internal override void OverrideCursor (IntPtr cursor)
661                 {
662                         display.OverrideCursor = cursor;
663                 }
664
665                 internal override PaintEventArgs PaintEventStart (IntPtr handle, bool client)
666                 {
667                         return display.PaintEventStart (handle, client);
668                 }
669
670                 internal override void PaintEventEnd (IntPtr handle, bool client)
671                 {
672                         display.PaintEventEnd (handle, client);
673                 }
674
675
676                 internal override bool PeekMessage (object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags)
677                 {
678                         return display.PeekMessage (queue_id, ref msg, hWnd, wFilterMin, wFilterMax, flags);
679                 }
680
681                 internal override bool PostMessage (IntPtr handle, Msg message, IntPtr wparam, IntPtr lparam)
682                 {
683                         return display.PostMessage (handle, message, wparam, lparam);
684                 }
685
686                 internal override void PostQuitMessage(int exitCode)
687                 {
688                         display.Flush ();
689                         ThreadQueue(Thread.CurrentThread).PostQuitState = true;
690                 }
691
692                 [MonoTODO]
693                 internal override void RequestAdditionalWM_NCMessages (IntPtr handle, bool hover, bool leave)
694                 {
695                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
696
697                         if (hwnd != null)
698                                 hwnd.RequestAdditionalWM_NCMessages (hover, leave);
699                 }
700                 
701                 internal override void RequestNCRecalc (IntPtr handle)
702                 {
703                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
704
705                         if (hwnd != null)
706                                 hwnd.RequestNCRecalc ();
707                 }
708
709                 internal override void ResetMouseHover (IntPtr handle)
710                 {
711                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
712
713                         display.ResetMouseHover (hwnd);
714                 }
715
716                 internal override void ScreenToClient(IntPtr handle, ref int x, ref int y)
717                 {
718                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
719
720                         if (hwnd != null)
721                                 hwnd.ScreenToClient (ref x, ref y);
722                 }
723
724                 internal override void ScreenToMenu (IntPtr handle, ref int x, ref int y)
725                 {
726                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
727
728                         if (hwnd != null)
729                                 hwnd.ScreenToMenu (ref x, ref y);
730                 }
731
732                 internal override void ScrollWindow (IntPtr handle, Rectangle area, int XAmount, int YAmount, bool with_children)
733                 {
734                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
735
736                         if (hwnd != null)
737                                 hwnd.ScrollWindow (area, XAmount, YAmount, with_children);
738                 }
739
740                 internal override void ScrollWindow(IntPtr handle, int XAmount, int YAmount, bool with_children)
741                 {
742                         X11Hwnd hwnd = (X11Hwnd)Hwnd.GetObjectFromWindow(handle);
743
744                         if (hwnd != null) {
745                                 Rectangle       rect;
746
747                                 rect = hwnd.ClientRect;
748                                 rect.X = 0;
749                                 rect.Y = 0;
750                                 hwnd.ScrollWindow (rect, XAmount, YAmount, with_children);
751                         }
752                 }
753
754                 internal override void SendAsyncMethod (AsyncMethodData method)
755                 {
756                         display.SendAsyncMethod (method);
757                 }
758
759                 // XXX this is likely shareable amongst other backends
760                 internal override IntPtr SendMessage (IntPtr handle, Msg message, IntPtr wParam, IntPtr lParam)
761                 {
762                         return display.SendMessage (handle, message, wParam, lParam);
763                 }
764
765                 internal override void SetAllowDrop (IntPtr handle, bool value)
766                 {
767                         // We allow drop on all windows
768                 }
769
770                 internal override DragDropEffects StartDrag (IntPtr handle, object data,
771                                                              DragDropEffects allowed_effects)
772                 {
773                         return display.StartDrag (handle, data, allowed_effects);
774                 }
775
776                 internal override void SetBorderStyle (IntPtr handle, FormBorderStyle border_style)
777                 {
778                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
779
780                         if (hwnd != null)
781                                 hwnd.SetBorderStyle (border_style);
782                 }
783
784                 internal override void SetCaretPos (IntPtr handle, int x, int y)
785                 {
786                         display.SetCaretPos (handle, x, y);
787                 }
788
789                 internal override void SetClipRegion (IntPtr handle, Region region)
790                 {
791                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
792
793                         if (hwnd != null)
794                                 hwnd.SetClipRegion (region);
795                 }
796
797                 internal override void SetCursor (IntPtr handle, IntPtr cursor)
798                 {
799                         display.SetCursor (handle, cursor);
800                 }
801
802                 internal override void SetCursorPos (IntPtr handle, int x, int y)
803                 {
804                         if (handle == IntPtr.Zero) {
805                                 display.SetCursorPos (x, y);
806                         }
807                         else {
808                                 X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
809
810                                 hwnd.SetCursorPos (x, y);
811                         }
812                 }
813
814                 internal override void SetFocus (IntPtr handle)
815                 {
816                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
817
818                         display.SetFocus (hwnd);
819                 }
820
821                 internal override void SetIcon(IntPtr handle, Icon icon)
822                 {
823                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);;
824
825                         if (hwnd != null)
826                                 hwnd.SetIcon (icon);
827                 }
828
829                 internal override void SetMenu(IntPtr handle, Menu menu)
830                 {
831                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
832
833                         hwnd.SetMenu (menu);
834                 }
835
836                 internal override void SetModal(IntPtr handle, bool Modal)
837                 {
838                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
839
840                         if (hwnd != null)
841                                 display.SetModal (hwnd, Modal);
842                 }
843
844                 internal override IntPtr SetParent(IntPtr handle, IntPtr parent)
845                 {
846                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
847                         X11Hwnd parent_hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(parent);
848
849                         if (hwnd != null)
850                                 hwnd.SetParent (parent_hwnd);
851
852                         return IntPtr.Zero;
853                 }
854
855                 internal override void SetTimer (Timer timer)
856                 {
857                         X11ThreadQueue queue = (X11ThreadQueue) MessageQueues [timer.thread];
858
859                         if (queue == null) {
860                                 // This isn't really an error, MS doesn't start the timer if
861                                 // it has no assosciated queue
862                                 return;
863                         }
864                         queue.SetTimer (timer);
865                 }
866
867                 internal override bool SetTopmost(IntPtr handle, IntPtr handle_owner, bool enabled)
868                 {
869                         X11Hwnd hwnd;
870
871                         hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
872
873                         if (hwnd == null)
874                                 return false;
875
876                         X11Hwnd hwnd_owner = (X11Hwnd)Hwnd.ObjectFromHandle(handle_owner);
877
878                         return hwnd.SetTopmost (hwnd_owner, enabled);
879                 }
880
881                 internal override bool SetVisible (IntPtr handle, bool visible, bool activate)
882                 {
883                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
884
885                         return hwnd != null && hwnd.SetVisible (visible, activate);
886                 }
887
888                 internal override void SetWindowMinMax (IntPtr handle, Rectangle maximized, Size min, Size max)
889                 {
890                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
891
892                         if (hwnd == null)
893                                 return;
894
895                         hwnd.SetMinMax (maximized, min, max);
896                 }
897
898                 internal override void SetWindowPos (IntPtr handle, int x, int y, int width, int height)
899                 {
900                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
901
902                         if (hwnd != null)
903                                 hwnd.SetPosition (x, y, width, height);
904                 }
905
906                 internal override void SetWindowState (IntPtr handle, FormWindowState state)
907                 {
908                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
909
910                         if (hwnd != null)
911                                 hwnd.SetWindowState (state);
912                 }
913
914                 internal override void SetWindowStyle (IntPtr handle, CreateParams cp)
915                 {
916                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
917
918                         if (hwnd != null) {
919                                 hwnd.SetHwndStyles (cp);
920                                 hwnd.SetWMStyles (cp);
921                         }
922                 }
923
924                 internal override double GetWindowTransparency (IntPtr handle)
925                 {
926                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
927
928                         if (hwnd != null)
929                                 return hwnd.GetWindowTransparency ();
930                         else
931                                 return 0.0;
932                 }
933
934                 internal override void SetWindowTransparency (IntPtr handle, double transparency, Color key)
935                 {
936                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
937
938                         if (hwnd != null)
939                                 hwnd.SetWindowTransparency (transparency, key);
940                 }
941
942                 internal override bool SetZOrder (IntPtr handle, IntPtr after_handle, bool top, bool bottom)
943                 {
944                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
945
946                         if (hwnd == null || !hwnd.mapped)
947                                 return false;
948
949                         X11Hwnd after_hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(after_handle);
950
951                         return hwnd.SetZOrder (after_hwnd, top, bottom);
952                 }
953
954                 internal override void ShowCursor (bool show)
955                 {
956                         display.ShowCursor (show);
957                 }
958
959                 internal override object StartLoop(Thread thread)
960                 {
961                         return (object) ThreadQueue(thread);
962                 }
963
964                 internal override TransparencySupport SupportsTransparency()
965                 {
966                         return display.SupportsTransparency ();
967                 }
968
969                 internal override bool SystrayAdd (IntPtr handle, string tip, Icon icon, out ToolTip tt)
970                 {
971                         return display.SystrayAdd (handle, tip, icon, out tt);
972                 }
973
974                 internal override bool SystrayChange (IntPtr handle, string tip, Icon icon, ref ToolTip tt)
975                 {
976                         return display.SystrayChange (handle, tip, icon, ref tt);
977                 }
978
979                 internal override void SystrayRemove (IntPtr handle, ref ToolTip tt)
980                 {
981                         display.SystrayRemove (handle, ref tt);
982                 }
983
984                 internal override bool Text (IntPtr handle, string text)
985                 {
986                         X11Hwnd hwnd = (X11Hwnd) Hwnd.ObjectFromHandle(handle);
987
988                         if (hwnd != null)
989                                 hwnd.Text = text;
990
991                         return true;
992                 }
993
994                 internal override bool TranslateMessage (ref MSG msg)
995                 {
996                         return display.TranslateMessage (ref msg);
997                 }
998
999                 internal override void UpdateWindow (IntPtr handle)
1000                 {
1001                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
1002
1003                         if (hwnd != null)
1004                                 hwnd.Update ();
1005                 }
1006
1007                 #endregion      // Public Static Methods
1008
1009                 #region Events
1010                 internal override event EventHandler Idle {
1011                         add {
1012                                 Console.WriteLine ("adding idle handler for thread {0}", Thread.CurrentThread.GetHashCode());
1013                                 X11ThreadQueue queue = ThreadQueue(Thread.CurrentThread);
1014                                 queue.Idle += value;
1015                         }
1016                         remove {
1017                                 X11ThreadQueue queue = ThreadQueue(Thread.CurrentThread);
1018                                 queue.Idle += value;
1019                         }
1020                 }
1021                 #endregion      // Events
1022         }
1023 }