Merge pull request #5560 from kumpera/wasm-work-p3
[mono.git] / mcs / class / System.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 CaptionHeight {
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 { return new Size (4, 4); }
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 bool MenuAccessKeysUnderlined {
190                         get {
191                                 return false;
192                         }
193                 }
194
195                 internal override Size MinimizedWindowSpacingSize {
196                         get { return new Size(1, 1); }
197                 } 
198
199                 internal override Size MinimumWindowSize {
200                         get { return new Size(1, 1); }
201                 } 
202
203                 internal override Keys ModifierKeys {
204                         get { return display.ModifierKeys; }
205                 }
206
207                 internal override Size SmallIconSize {
208                         get { return display.SmallIconSize; }
209                 }
210
211                 internal override int MouseButtonCount {
212                         get { return 3; /* FIXME - should detect this somehow.. */}
213                 } 
214
215                 internal override bool MouseButtonsSwapped {
216                         get { return false; /*FIXME - how to detect? */}
217                 } 
218
219                 internal override Size MouseHoverSize {
220                         get { return new Size (1, 1); }
221                 }
222
223                 internal override int MouseHoverTime {
224                         get { return display.MouseHoverTime; }
225                 }
226
227                 internal override bool MouseWheelPresent {
228                         get { return true; /* FIXME - how to detect? */ }
229                 } 
230
231                 internal override Rectangle VirtualScreen {
232                         get { return display.VirtualScreen; }
233                 } 
234
235                 internal override Rectangle WorkingArea {
236                         get { return display.WorkingArea; }
237                 }
238
239                 internal override bool ThemesEnabled {
240                         get { return XplatUIX11_new.themes_enabled; }
241                 }
242  
243
244                 #endregion      // Public properties
245
246                 #region Public Static Methods
247                 internal override void RaiseIdle (EventArgs e)
248                 {
249                         X11ThreadQueue queue = ThreadQueue (Thread.CurrentThread);
250                         queue.OnIdle (e);
251                 }
252
253                 internal override IntPtr InitializeDriver ()
254                 {
255                         lock (this) {
256                                 if (display == null)
257                                         display = new X11Display (Xlib.XOpenDisplay(IntPtr.Zero));
258                         }
259                         return IntPtr.Zero;
260                 }
261
262                 internal override void ShutdownDriver(IntPtr token)
263                 {
264                         lock (this) {
265                                 if (display != null) {
266                                         display.Close ();
267                                         display = null;
268                                 }
269                         }
270                 }
271
272                 internal override void EnableThemes()
273                 {
274                         themes_enabled = true;
275                 }
276
277                 internal override void Activate (IntPtr handle)
278                 {
279                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
280
281                         if (hwnd != null)
282                                 hwnd.Activate ();
283                 }
284
285                 internal override void AudibleAlert()
286                 {
287                         display.AudibleAlert ();
288                 }
289
290
291                 internal override void CaretVisible (IntPtr handle, bool visible)
292                 {
293                         display.CaretVisible (handle, visible);
294                 }
295
296                 // XXX this implementation should probably be shared between all non-win32 backends
297                 internal override bool CalculateWindowRect (ref Rectangle ClientRect, CreateParams cp, Menu menu, out Rectangle WindowRect)
298                 {
299                         WindowRect = Hwnd.GetWindowRectangle (cp, menu, ClientRect);
300                         return true;
301                 }
302
303                 internal override void ClientToScreen (IntPtr handle, ref int x, ref int y)
304                 {
305                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
306
307                         if (hwnd != null)
308                                 hwnd.ClientToScreen (ref x, ref y);
309                 }
310
311                 internal override int[] ClipboardAvailableFormats (IntPtr handle)
312                 {
313                         return display.ClipboardAvailableFormats (handle);
314                 }
315
316                 internal override void ClipboardClose (IntPtr handle)
317                 {
318                         display.ClipboardClose (handle);
319                 }
320
321                 internal override int ClipboardGetID (IntPtr handle, string format)
322                 {
323                         return display.ClipboardGetID (handle, format);
324                 }
325
326                 internal override IntPtr ClipboardOpen (bool primary_selection)
327                 {
328                         return display.ClipboardOpen (primary_selection);
329                 }
330
331                 internal override object ClipboardRetrieve (IntPtr handle, int type, XplatUI.ClipboardToObject converter)
332                 {
333                         return display.ClipboardRetrieve (handle, type, converter);
334                 }
335
336                 internal override void ClipboardStore (IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter)
337                 {
338                         display.ClipboardStore (handle, obj, type, converter);
339                 }
340
341                 internal override void CreateCaret (IntPtr handle, int width, int height)
342                 {
343                         display.CreateCaret (handle, width, height);
344                 }
345
346                 internal override IntPtr CreateWindow (CreateParams cp)
347                 {
348                         X11Hwnd hwnd = new X11Hwnd (display);
349
350                         hwnd.CreateWindow (cp);
351
352                         return hwnd.Handle;
353                 }
354
355                 internal override IntPtr CreateWindow (IntPtr Parent, int X, int Y, int Width, int Height)
356                 {
357                         CreateParams create_params = new CreateParams();
358
359                         create_params.Caption = "";
360                         create_params.X = X;
361                         create_params.Y = Y;
362                         create_params.Width = Width;
363                         create_params.Height = Height;
364
365                         create_params.ClassName = XplatUI.DefaultClassName;
366                         create_params.ClassStyle = 0;
367                         create_params.ExStyle = 0;
368                         create_params.Parent = IntPtr.Zero;
369                         create_params.Param = 0;
370
371                         return CreateWindow (create_params);
372                 }
373
374                 internal override IntPtr DefineCursor (Bitmap bitmap, Bitmap mask, Color cursor_pixel, Color mask_pixel, int xHotSpot, int yHotSpot)
375                 {
376                         return display.DefineCursor (bitmap, mask, cursor_pixel, mask_pixel, xHotSpot, yHotSpot);
377                 }
378                 internal override Bitmap DefineStdCursorBitmap (StdCursor id) 
379                 {
380                         return display.DefineStdCursorBitmap (id);
381                 }
382                 internal override IntPtr DefineStdCursor (StdCursor id)
383                 {
384                         return display.DefineStdCursor (id);
385                 }
386
387                 internal override IntPtr DefWndProc(ref Message msg)
388                 {
389                         X11Hwnd hwnd = (X11Hwnd)Hwnd.GetObjectFromWindow(msg.HWnd);
390
391                         if (hwnd == null)
392                                 return IntPtr.Zero;
393
394                         return hwnd.DefWndProc (ref msg);
395                 }
396
397                 internal override void DestroyCaret (IntPtr handle)
398                 {
399                         display.DestroyCaret (handle);
400                 }
401
402                 internal override void DestroyCursor(IntPtr cursor)
403                 {
404                         display.DestroyCursor (cursor);
405                 }
406
407                 internal override void DestroyWindow (IntPtr handle) {
408                         X11Hwnd hwnd;
409
410                         hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
411
412                         if (hwnd == null) {
413 #if DriverDebug || DriverDebugDestroy
414                                 Console.WriteLine("window {0:X} already destroyed", handle.ToInt32());
415 #endif
416                                 return;
417                         }
418
419 #if DriverDebug || DriverDebugDestroy
420                         Console.WriteLine("Destroying window {0}", XplatUI.Window(hwnd.ClientWindow));
421 #endif
422
423                         display.DestroyWindow (hwnd);
424                 }
425
426                 internal override IntPtr DispatchMessage(ref MSG msg)
427                 {
428                         return display.DispatchMessage (ref msg);
429                 }
430
431                 internal override void DrawReversibleLine (Point start, Point end, Color backColor)
432                 {
433                         display.DrawReversibleLine (start, end, backColor);
434                 }
435
436                 internal override void FillReversibleRectangle (Rectangle rectangle, Color backColor)
437                 {
438                         display.FillReversibleRectangle (rectangle, backColor);
439                 }
440
441                 internal override void DrawReversibleFrame (Rectangle rectangle, Color backColor, FrameStyle style)
442                 {
443                         display.DrawReversibleFrame (rectangle, backColor, style);
444                 }
445
446                 internal override void DrawReversibleRectangle (IntPtr handle, Rectangle rect, int line_width)
447                 {
448                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
449
450                         if (hwnd != null)
451                                 hwnd.DrawReversibleRectangle (rect, line_width);
452                 }
453
454                 internal override void DoEvents ()
455                 {
456                         X11ThreadQueue queue = ThreadQueue (Thread.CurrentThread);
457                         display.DoEvents (queue);
458                 }
459
460                 internal override void EnableWindow (IntPtr handle, bool Enable)
461                 {
462                         Hwnd    hwnd;
463
464                         hwnd = Hwnd.ObjectFromHandle(handle);
465                         if (hwnd != null)
466                                 hwnd.Enabled = Enable;
467                 }
468
469                 internal override void EndLoop (Thread thread)
470                 {
471                         // This is where we one day will shut down the loop for the thread
472                 }
473
474
475                 internal override IntPtr GetActive()
476                 {
477                         X11Hwnd hwnd = display.GetActiveWindow ();
478
479                         return (hwnd == null) ? IntPtr.Zero : hwnd.Handle;
480                 }
481
482                 internal override Region GetClipRegion (IntPtr handle)
483                 {
484                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
485
486                         return (hwnd == null) ? null : hwnd.GetClipRegion ();
487                 }
488
489                 internal override void GetCursorInfo(IntPtr cursor, out int width, out int height, out int hotspot_x, out int hotspot_y)
490                 {
491                         width = 20;
492                         height = 20;
493                         hotspot_x = 0;
494                         hotspot_y = 0;
495                 }
496
497                 internal override void GetDisplaySize(out Size size)
498                 {
499                         display.GetDisplaySize (out size);
500                 }
501
502                 internal override SizeF GetAutoScaleSize (Font font)
503                 {
504                         return display.GetAutoScaleSize (font);
505                 }
506
507                 // XXX this should be someplace shareable by all non-win32 backends..  like in Hwnd itself.
508                 // maybe a Hwnd.ParentHandle property
509                 internal override IntPtr GetParent (IntPtr handle)
510                 {
511                         Hwnd    hwnd;
512
513                         hwnd = Hwnd.ObjectFromHandle(handle);
514                         if (hwnd != null && hwnd.parent != null) {
515                                 return hwnd.parent.Handle;
516                         }
517                         return IntPtr.Zero;
518                 }
519
520                 // This is a nop on win32 and x11
521                 internal override IntPtr GetPreviousWindow(IntPtr handle) {
522                         return handle;
523                 }
524
525                 internal override void GetCursorPos (IntPtr handle, out int x, out int y)
526                 {
527                         display.GetCursorPos ((X11Hwnd)Hwnd.ObjectFromHandle(handle),
528                                               out x, out y);
529                 }
530
531                 internal override IntPtr GetFocus()
532                 {
533                         return display.GetFocus ();
534                 }
535
536                 // XXX this should be shared amongst non-win32 backends
537                 internal override bool GetFontMetrics (Graphics g, Font font, out int ascent, out int descent)
538                 {
539                         FontFamily ff = font.FontFamily;
540                         ascent = ff.GetCellAscent (font.Style);
541                         descent = ff.GetCellDescent (font.Style);
542                         return true;
543                 }
544
545
546                 // XXX this should be shared amongst non-win32 backends
547                 internal override Point GetMenuOrigin (IntPtr handle)
548                 {
549                         Hwnd    hwnd;
550
551                         hwnd = Hwnd.ObjectFromHandle(handle);
552
553                         if (hwnd != null)
554                                 return hwnd.MenuOrigin;
555
556                         return Point.Empty;
557                 }
558
559                 internal override bool GetMessage (object queue_id, ref MSG msg, IntPtr handle, int wFilterMin, int wFilterMax)
560                 {
561                         return display.GetMessage (queue_id, ref msg, handle, wFilterMin, wFilterMax);
562                 }
563
564                 internal override bool GetText (IntPtr handle, out string text)
565                 {
566                         X11Hwnd hwnd = (X11Hwnd) Hwnd.ObjectFromHandle(handle);
567
568                         text = "";
569                         return hwnd != null && hwnd.GetText (out text);
570                 }
571
572                 internal override void GetWindowPos (IntPtr handle, bool is_toplevel,
573                                                      out int x, out int y,
574                                                      out int width, out int height,
575                                                      out int client_width, out int client_height)
576                 {
577                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
578
579                         if (hwnd != null) {
580                                 hwnd.GetPosition (is_toplevel, out x, out y, out width, out height, out client_width, out client_height);
581                         }
582                         else {
583                                 // Should we throw an exception or fail silently?
584                                 // throw new ArgumentException("Called with an invalid window handle", "handle");
585
586                                 x = 0;
587                                 y = 0;
588                                 width = 0;
589                                 height = 0;
590                                 client_width = 0;
591                                 client_height = 0;
592                         }
593                 }
594
595                 internal override FormWindowState GetWindowState (IntPtr handle)
596                 {
597                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
598
599                         if (hwnd == null)
600                                 return FormWindowState.Normal; // XXX should we throw an exception here?  probably
601
602                         return hwnd.GetWindowState ();
603                 }
604
605                 internal override void GrabInfo (out IntPtr handle, out bool GrabConfined, out Rectangle GrabArea)
606                 {
607                         display.GrabInfo (out handle, out GrabConfined, out GrabArea);
608                 }
609
610                 internal override void GrabWindow (IntPtr handle, IntPtr confine_to_handle)
611                 {
612                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
613                         X11Hwnd confine_to_hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(confine_to_handle);
614
615                         display.GrabWindow (hwnd, confine_to_hwnd);
616                 }
617
618                 internal override void UngrabWindow (IntPtr handle)
619                 {
620                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
621
622                         display.UngrabWindow (hwnd);
623                 }
624
625                 internal override void HandleException(Exception e) {
626                         StackTrace st = new StackTrace(e, true);
627                         Console.WriteLine("Exception '{0}'", e.Message+st.ToString());
628                         Console.WriteLine("{0}{1}", e.Message, st.ToString());
629                 }
630
631                 internal override void Invalidate (IntPtr handle, Rectangle rc, bool clear)
632                 {
633                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
634
635                         hwnd.Invalidate (rc, clear);
636                 }
637
638                 internal override void InvalidateNC (IntPtr handle)
639                 {
640                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
641
642                         hwnd.InvalidateNC ();
643                 }
644
645                 internal override bool IsEnabled(IntPtr handle)
646                 {
647                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle (handle);
648
649                         return hwnd != null && hwnd.Enabled;
650                 }
651                 
652                 internal override bool IsVisible(IntPtr handle)
653                 {
654                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle (handle);
655
656                         return hwnd != null && hwnd.Visible;
657                 }
658
659                 internal override void KillTimer (Timer timer)
660                 {
661                         X11ThreadQueue queue = (X11ThreadQueue) MessageQueues [timer.thread];
662
663                         if (queue == null) {
664                                 // This isn't really an error, MS doesn't start the timer if
665                                 // it has no assosciated queue
666                                 return;
667                         }
668                         queue.KillTimer (timer);
669                 }
670
671                 internal override void MenuToScreen (IntPtr handle, ref int x, ref int y)
672                 {
673                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
674
675                         if (hwnd != null)
676                                 hwnd.MenuToScreen (ref x, ref y);
677                 }
678
679                 internal override void OverrideCursor (IntPtr cursor)
680                 {
681                         display.OverrideCursor = cursor;
682                 }
683
684                 internal override PaintEventArgs PaintEventStart (ref Message m, IntPtr handle, bool client)
685                 {
686                         return display.PaintEventStart (ref m, handle, client);
687                 }
688
689                 internal override void PaintEventEnd (ref Message m, IntPtr handle, bool client)
690                 {
691                         display.PaintEventEnd (ref m, handle, client);
692                 }
693
694
695                 internal override bool PeekMessage (object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags)
696                 {
697                         return display.PeekMessage (queue_id, ref msg, hWnd, wFilterMin, wFilterMax, flags);
698                 }
699
700                 internal override bool PostMessage (IntPtr handle, Msg message, IntPtr wparam, IntPtr lparam)
701                 {
702                         return display.PostMessage (handle, message, wparam, lparam);
703                 }
704
705                 internal override void PostQuitMessage(int exitCode)
706                 {
707                         display.PostMessage (display.FosterParent.Handle, Msg.WM_QUIT, IntPtr.Zero, IntPtr.Zero);
708                         display.Flush ();
709                 }
710
711                 [MonoTODO]
712                 internal override void RequestAdditionalWM_NCMessages (IntPtr handle, bool hover, bool leave)
713                 {
714                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
715
716                         if (hwnd != null)
717                                 hwnd.RequestAdditionalWM_NCMessages (hover, leave);
718                 }
719                 
720                 internal override void RequestNCRecalc (IntPtr handle)
721                 {
722                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
723
724                         if (hwnd != null)
725                                 hwnd.RequestNCRecalc ();
726                 }
727
728                 internal override void ResetMouseHover (IntPtr handle)
729                 {
730                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
731
732                         display.ResetMouseHover (hwnd);
733                 }
734
735                 internal override void ScreenToClient(IntPtr handle, ref int x, ref int y)
736                 {
737                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
738
739                         if (hwnd != null)
740                                 hwnd.ScreenToClient (ref x, ref y);
741                 }
742
743                 internal override void ScreenToMenu (IntPtr handle, ref int x, ref int y)
744                 {
745                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
746
747                         if (hwnd != null)
748                                 hwnd.ScreenToMenu (ref x, ref y);
749                 }
750
751                 internal override void ScrollWindow (IntPtr handle, Rectangle area, int XAmount, int YAmount, bool with_children)
752                 {
753                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
754
755                         if (hwnd != null)
756                                 hwnd.ScrollWindow (area, XAmount, YAmount, with_children);
757                 }
758
759                 internal override void ScrollWindow(IntPtr handle, int XAmount, int YAmount, bool with_children)
760                 {
761                         X11Hwnd hwnd = (X11Hwnd)Hwnd.GetObjectFromWindow(handle);
762
763                         if (hwnd != null) {
764                                 Rectangle       rect;
765
766                                 rect = hwnd.ClientRect;
767                                 rect.X = 0;
768                                 rect.Y = 0;
769                                 hwnd.ScrollWindow (rect, XAmount, YAmount, with_children);
770                         }
771                 }
772
773                 internal override void SendAsyncMethod (AsyncMethodData method)
774                 {
775                         display.SendAsyncMethod (method);
776                 }
777
778                 // XXX this is likely shareable amongst other backends
779                 internal override IntPtr SendMessage (IntPtr handle, Msg message, IntPtr wParam, IntPtr lParam)
780                 {
781                         return display.SendMessage (handle, message, wParam, lParam);
782                 }
783
784                 internal override int SendInput(IntPtr handle, Queue keys) { 
785                         return display.SendInput(handle, keys);
786                 }
787
788
789                 internal override void SetAllowDrop (IntPtr handle, bool value)
790                 {
791                         // We allow drop on all windows
792                 }
793
794                 internal override DragDropEffects StartDrag (IntPtr handle, object data,
795                                                              DragDropEffects allowed_effects)
796                 {
797                         return display.StartDrag (handle, data, allowed_effects);
798                 }
799
800                 internal override void SetBorderStyle (IntPtr handle, FormBorderStyle border_style)
801                 {
802                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
803
804                         if (hwnd != null)
805                                 hwnd.SetBorderStyle (border_style);
806                 }
807
808                 internal override void SetCaretPos (IntPtr handle, int x, int y)
809                 {
810                         display.SetCaretPos (handle, x, y);
811                 }
812
813                 internal override void SetClipRegion (IntPtr handle, Region region)
814                 {
815                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
816
817                         if (hwnd != null)
818                                 hwnd.SetClipRegion (region);
819                 }
820
821                 internal override void SetCursor (IntPtr handle, IntPtr cursor)
822                 {
823                         display.SetCursor (handle, cursor);
824                 }
825
826                 internal override void SetCursorPos (IntPtr handle, int x, int y)
827                 {
828                         if (handle == IntPtr.Zero) {
829                                 display.SetCursorPos (x, y);
830                         }
831                         else {
832                                 X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
833
834                                 hwnd.SetCursorPos (x, y);
835                         }
836                 }
837
838                 internal override void SetFocus (IntPtr handle)
839                 {
840                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
841
842                         display.SetFocus (hwnd);
843                 }
844
845                 internal override void SetIcon(IntPtr handle, Icon icon)
846                 {
847                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);;
848
849                         if (hwnd != null)
850                                 hwnd.SetIcon (icon);
851                 }
852
853                 internal override void SetMenu(IntPtr handle, Menu menu)
854                 {
855                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
856
857                         hwnd.SetMenu (menu);
858                 }
859
860                 internal override void SetModal(IntPtr handle, bool Modal)
861                 {
862                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
863
864                         if (hwnd != null)
865                                 display.SetModal (hwnd, Modal);
866                 }
867
868                 internal override IntPtr SetParent(IntPtr handle, IntPtr parent)
869                 {
870                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
871                         X11Hwnd parent_hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(parent);
872
873                         if (hwnd != null)
874                                 hwnd.SetParent (parent_hwnd);
875
876                         return IntPtr.Zero;
877                 }
878
879                 internal override void SetTimer (Timer timer)
880                 {
881                         X11ThreadQueue queue = (X11ThreadQueue) MessageQueues [timer.thread];
882
883                         if (queue == null) {
884                                 // This isn't really an error, MS doesn't start the timer if
885                                 // it has no assosciated queue
886                                 return;
887                         }
888                         queue.SetTimer (timer);
889                 }
890
891                 internal override bool SetTopmost(IntPtr handle, bool enabled)
892                 {
893                         X11Hwnd hwnd = (X11Hwnd) Hwnd.ObjectFromHandle (handle);
894
895                         if (hwnd == null)
896                                 return false;
897
898                         return hwnd.SetTopmost (enabled);
899                 }
900
901                 internal override bool SetOwner(IntPtr handle, IntPtr handle_owner)
902                 {
903                         X11Hwnd hwnd;
904
905                         hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
906
907                         if (hwnd == null)
908                                 return false;
909
910                         X11Hwnd hwnd_owner = (X11Hwnd)Hwnd.ObjectFromHandle(handle_owner);
911
912                         return hwnd.SetOwner (hwnd_owner);
913                 }
914
915                 internal override bool SetVisible (IntPtr handle, bool visible, bool activate)
916                 {
917                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
918
919                         return hwnd != null && hwnd.SetVisible (visible, activate);
920                 }
921
922                 internal override void SetWindowMinMax (IntPtr handle, Rectangle maximized, Size min, Size max)
923                 {
924                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
925
926                         if (hwnd == null)
927                                 return;
928
929                         hwnd.SetMinMax (maximized, min, max);
930                 }
931
932                 internal override void SetWindowPos (IntPtr handle, int x, int y, int width, int height)
933                 {
934                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
935
936                         if (hwnd != null)
937                                 hwnd.SetPosition (x, y, width, height);
938                 }
939
940                 internal override void SetWindowState (IntPtr handle, FormWindowState state)
941                 {
942                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
943
944                         if (hwnd != null)
945                                 hwnd.SetWindowState (state);
946                 }
947
948                 internal override void SetWindowStyle (IntPtr handle, CreateParams cp)
949                 {
950                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
951
952                         if (hwnd != null) {
953                                 hwnd.SetHwndStyles (cp);
954                                 hwnd.SetWMStyles (cp);
955                         }
956                 }
957
958                 internal override double GetWindowTransparency (IntPtr handle)
959                 {
960                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
961
962                         if (hwnd != null)
963                                 return hwnd.GetWindowTransparency ();
964                         else
965                                 return 0.0;
966                 }
967
968                 internal override void SetWindowTransparency (IntPtr handle, double transparency, Color key)
969                 {
970                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
971
972                         if (hwnd != null)
973                                 hwnd.SetWindowTransparency (transparency, key);
974                 }
975
976                 internal override bool SetZOrder (IntPtr handle, IntPtr after_handle, bool top, bool bottom)
977                 {
978                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
979
980                         if (hwnd == null || !hwnd.mapped)
981                                 return false;
982
983                         X11Hwnd after_hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(after_handle);
984
985                         return hwnd.SetZOrder (after_hwnd, top, bottom);
986                 }
987
988                 internal override void ShowCursor (bool show)
989                 {
990                         display.ShowCursor (show);
991                 }
992
993                 internal override object StartLoop(Thread thread)
994                 {
995                         return (object) ThreadQueue(thread);
996                 }
997
998                 internal override TransparencySupport SupportsTransparency()
999                 {
1000                         return display.SupportsTransparency ();
1001                 }
1002
1003                 internal override bool SystrayAdd (IntPtr handle, string tip, Icon icon, out ToolTip tt)
1004                 {
1005                         return display.SystrayAdd (handle, tip, icon, out tt);
1006                 }
1007
1008                 internal override bool SystrayChange (IntPtr handle, string tip, Icon icon, ref ToolTip tt)
1009                 {
1010                         return display.SystrayChange (handle, tip, icon, ref tt);
1011                 }
1012
1013                 internal override void SystrayRemove (IntPtr handle, ref ToolTip tt)
1014                 {
1015                         display.SystrayRemove (handle, ref tt);
1016                 }
1017
1018                 NotifyIcon.BalloonWindow balloon_window;
1019
1020                 internal override void SystrayBalloon(IntPtr handle, int timeout, string title, string text, ToolTipIcon icon)
1021                 {
1022                         Control control = Control.FromHandle(handle);
1023                         
1024                         if (control == null)
1025                                 return;
1026
1027                         if (balloon_window != null) {
1028                                 balloon_window.Close ();
1029                                 balloon_window.Dispose ();
1030                         }
1031
1032                         balloon_window = new NotifyIcon.BalloonWindow (handle);
1033                         balloon_window.Title = title;
1034                         balloon_window.Text = text;
1035                         balloon_window.Timeout = timeout;
1036                         balloon_window.Show ();
1037                         
1038                         SendMessage(handle, Msg.WM_USER, IntPtr.Zero, (IntPtr) Msg.NIN_BALLOONSHOW);    
1039                 }
1040
1041                 internal override bool Text (IntPtr handle, string text)
1042                 {
1043                         X11Hwnd hwnd = (X11Hwnd) Hwnd.ObjectFromHandle(handle);
1044
1045                         if (hwnd != null)
1046                                 hwnd.Text = text;
1047
1048                         return true;
1049                 }
1050
1051                 internal override bool TranslateMessage (ref MSG msg)
1052                 {
1053                         return display.TranslateMessage (ref msg);
1054                 }
1055
1056                 internal override void UpdateWindow (IntPtr handle)
1057                 {
1058                         X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
1059
1060                         if (hwnd != null)
1061                                 hwnd.Update ();
1062                 }
1063
1064                 internal override void CreateOffscreenDrawable (IntPtr handle,
1065                                                                 int width, int height,
1066                                                                 out object offscreen_drawable)
1067                 {
1068                         display.CreateOffscreenDrawable (handle, width, height,
1069                                                          out offscreen_drawable);
1070                 }
1071
1072                 internal override void DestroyOffscreenDrawable (object offscreen_drawable)
1073                 {
1074                         display.DestroyOffscreenDrawable (offscreen_drawable);
1075                 }
1076
1077                 internal override Graphics GetOffscreenGraphics (object offscreen_drawable)
1078                 {
1079                         return display.GetOffscreenGraphics (offscreen_drawable);
1080                 }
1081
1082                 internal override void BlitFromOffscreen (IntPtr dest_handle,
1083                                                           Graphics dest_dc,
1084                                                           object offscreen_drawable,
1085                                                           Graphics offscreen_dc,
1086                                                           Rectangle r)
1087                 {
1088                         display.BlitFromOffscreen (dest_handle, dest_dc, offscreen_drawable, offscreen_dc, r);
1089                 }
1090
1091                 #endregion      // Public Static Methods
1092
1093                 #region Events
1094                 internal override event EventHandler Idle {
1095                         add {
1096                                 Console.WriteLine ("adding idle handler for thread {0}", Thread.CurrentThread.GetHashCode());
1097                                 X11ThreadQueue queue = ThreadQueue(Thread.CurrentThread);
1098                                 queue.Idle += value;
1099                         }
1100                         remove {
1101                                 X11ThreadQueue queue = ThreadQueue(Thread.CurrentThread);
1102                                 queue.Idle += value;
1103                         }
1104                 }
1105                 #endregion      // Events
1106         }
1107 }