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:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
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.
20 // Copyright (c) 2004-2006 Novell, Inc.
23 // Peter Bartok pbartok@novell.com
24 // Alexander Olk alex.olk@googlemail.com
29 // This driver understands the following environment variables: (Set the var to enable feature)
31 // MONO_XEXCEPTIONS = throw an exception when a X11 error is encountered;
32 // by default a message is displayed but execution continues
34 // MONO_XSYNC = perform all X11 commands synchronous; this is slower but
35 // helps in debugging errors
38 // NOT COMPLETE - WORK IN PROGRESS
40 // One feature of the driver is, that PaintEventstart returns a graphics context created from a offscreen drawable (pixmap)
42 // define to log Window handles and relationships to stdout
45 // Extra detailed debug
46 #undef DriverDebugExtra
49 using System
.ComponentModel
;
50 using System
.Collections
;
51 using System
.Diagnostics
;
53 using System
.Drawing
.Drawing2D
;
54 using System
.Drawing
.Imaging
;
57 using System
.Net
.Sockets
;
58 using System
.Reflection
;
59 using System
.Runtime
.InteropServices
;
61 using System
.Threading
;
63 // Only do the poll when building with mono for now
65 using Mono
.Unix
.Native
;
69 namespace System
.Windows
.Forms
{
70 internal class XplatUIX11GTK
: XplatUIDriver
{
72 internal enum GdkWindowClass
{
77 internal enum GdkWindowType
{
86 internal enum GdkWindowHints
{
87 GDK_HINT_POS
= 1 << 0,
88 GDK_HINT_MIN_SIZE
= 1 << 1,
89 GDK_HINT_MAX_SIZE
= 1 << 2,
90 GDK_HINT_BASE_SIZE
= 1 << 3,
91 GDK_HINT_ASPECT
= 1 << 4,
92 GDK_HINT_RESIZE_INC
= 1 << 5,
93 GDK_HINT_WIN_GRAVITY
= 1 << 6,
94 GDK_HINT_USER_POS
= 1 << 7,
95 GDK_HINT_USER_SIZE
= 1 << 8
98 internal enum GdkGravity
{
99 GDK_GRAVITY_NORTH_WEST
= 1,
101 GDK_GRAVITY_NORTH_EAST
,
105 GDK_GRAVITY_SOUTH_WEST
,
107 GDK_GRAVITY_SOUTH_EAST
,
111 internal enum GdkWindowEdge
{
112 GDK_WINDOW_EDGE_NORTH_WEST
,
113 GDK_WINDOW_EDGE_NORTH
,
114 GDK_WINDOW_EDGE_NORTH_EAST
,
115 GDK_WINDOW_EDGE_WEST
,
116 GDK_WINDOW_EDGE_EAST
,
117 GDK_WINDOW_EDGE_SOUTH_WEST
,
118 GDK_WINDOW_EDGE_SOUTH
,
119 GDK_WINDOW_EDGE_SOUTH_EAST
122 internal enum GdkWindowTypeHint
{
123 GDK_WINDOW_TYPE_HINT_NORMAL
,
124 GDK_WINDOW_TYPE_HINT_DIALOG
,
125 GDK_WINDOW_TYPE_HINT_MENU
,
126 GDK_WINDOW_TYPE_HINT_TOOLBAR
,
127 GDK_WINDOW_TYPE_HINT_SPLASHSCREEN
,
128 GDK_WINDOW_TYPE_HINT_UTILITY
,
129 GDK_WINDOW_TYPE_HINT_DOCK
,
130 GDK_WINDOW_TYPE_HINT_DESKTOP
133 internal enum GdkWindowAttributesType
{
134 GDK_WA_TITLE
= 1 << 1,
137 GDK_WA_CURSOR
= 1 << 4,
138 GDK_WA_COLORMAP
= 1 << 5,
139 GDK_WA_VISUAL
= 1 << 6,
140 GDK_WA_WMCLASS
= 1 << 7,
141 GDK_WA_NOREDIR
= 1 << 8
144 internal enum GdkEventMask
{
145 GDK_EXPOSURE_MASK
= 1 << 1,
146 GDK_POINTER_MOTION_MASK
= 1 << 2,
147 GDK_POINTER_MOTION_HINT_MASK
= 1 << 3,
148 GDK_BUTTON_MOTION_MASK
= 1 << 4,
149 GDK_BUTTON1_MOTION_MASK
= 1 << 5,
150 GDK_BUTTON2_MOTION_MASK
= 1 << 6,
151 GDK_BUTTON3_MOTION_MASK
= 1 << 7,
152 GDK_BUTTON_PRESS_MASK
= 1 << 8,
153 GDK_BUTTON_RELEASE_MASK
= 1 << 9,
154 GDK_KEY_PRESS_MASK
= 1 << 10,
155 GDK_KEY_RELEASE_MASK
= 1 << 11,
156 GDK_ENTER_NOTIFY_MASK
= 1 << 12,
157 GDK_LEAVE_NOTIFY_MASK
= 1 << 13,
158 GDK_FOCUS_CHANGE_MASK
= 1 << 14,
159 GDK_STRUCTURE_MASK
= 1 << 15,
160 GDK_PROPERTY_CHANGE_MASK
= 1 << 16,
161 GDK_VISIBILITY_NOTIFY_MASK
= 1 << 17,
162 GDK_PROXIMITY_IN_MASK
= 1 << 18,
163 GDK_PROXIMITY_OUT_MASK
= 1 << 19,
164 GDK_SUBSTRUCTURE_MASK
= 1 << 20,
165 GDK_SCROLL_MASK
= 1 << 21,
166 GDK_ALL_EVENTS_MASK
= 0x3FFFFE
169 internal enum GdkEventType
{
174 GDK_MOTION_NOTIFY
= 3,
175 GDK_BUTTON_PRESS
= 4,
176 GDK_2BUTTON_PRESS
= 5,
177 GDK_3BUTTON_PRESS
= 6,
178 GDK_BUTTON_RELEASE
= 7,
181 GDK_ENTER_NOTIFY
= 10,
182 GDK_LEAVE_NOTIFY
= 11,
183 GDK_FOCUS_CHANGE
= 12,
187 GDK_PROPERTY_NOTIFY
= 16,
188 GDK_SELECTION_CLEAR
= 17,
189 GDK_SELECTION_REQUEST
= 18,
190 GDK_SELECTION_NOTIFY
= 19,
191 GDK_PROXIMITY_IN
= 20,
192 GDK_PROXIMITY_OUT
= 21,
195 GDK_DRAG_MOTION
= 24,
196 GDK_DRAG_STATUS
= 25,
198 GDK_DROP_FINISHED
= 27,
199 GDK_CLIENT_EVENT
= 28,
200 GDK_VISIBILITY_NOTIFY
= 29,
203 GDK_WINDOW_STATE
= 32,
205 GDK_OWNER_CHANGE
= 34,
209 internal enum GdkWMDecoration
{
210 GDK_DECOR_ALL
= 1 << 0,
211 GDK_DECOR_BORDER
= 1 << 1,
212 GDK_DECOR_RESIZEH
= 1 << 2,
213 GDK_DECOR_TITLE
= 1 << 3,
214 GDK_DECOR_MENU
= 1 << 4,
215 GDK_DECOR_MINIMIZE
= 1 << 5,
216 GDK_DECOR_MAXIMIZE
= 1 << 6
219 internal enum GdkWMFunction
{
220 GDK_FUNC_ALL
= 1 << 0,
221 GDK_FUNC_RESIZE
= 1 << 1,
222 GDK_FUNC_MOVE
= 1 << 2,
223 GDK_FUNC_MINIMIZE
= 1 << 3,
224 GDK_FUNC_MAXIMIZE
= 1 << 4,
225 GDK_FUNC_CLOSE
= 1 << 5
228 internal enum GdkCursorType
{
231 GDK_BASED_ARROW_DOWN
= 4,
232 GDK_BASED_ARROW_UP
= 6,
235 GDK_BOTTOM_LEFT_CORNER
= 12,
236 GDK_BOTTOM_RIGHT_CORNER
= 14,
237 GDK_BOTTOM_SIDE
= 16,
245 GDK_CROSS_REVERSE
= 32,
247 GDK_DIAMOND_CROSS
= 36,
250 GDK_DOUBLE_ARROW
= 42,
251 GDK_DRAFT_LARGE
= 44,
252 GDK_DRAFT_SMALL
= 46,
270 GDK_MIDDLEBUTTON
= 82,
275 GDK_QUESTION_ARROW
= 92,
279 GDK_RIGHTBUTTON
= 100,
282 GDK_SB_DOWN_ARROW
= 106,
283 GDK_SB_H_DOUBLE_ARROW
= 108,
284 GDK_SB_LEFT_ARROW
= 110,
285 GDK_SB_RIGHT_ARROW
= 112,
286 GDK_SB_UP_ARROW
= 114,
287 GDK_SB_V_DOUBLE_ARROW
= 116,
295 GDK_TOP_LEFT_ARROW
= 132,
296 GDK_TOP_LEFT_CORNER
= 134,
297 GDK_TOP_RIGHT_CORNER
= 136,
307 GDK_CURSOR_IS_PIXMAP
= -1
310 internal enum GdkPropMode
{
311 GDK_PROP_MODE_REPLACE
,
312 GDK_PROP_MODE_PREPEND
,
316 [StructLayout (LayoutKind
.Sequential
)]
317 internal struct GdkGeometry
{
318 internal int min_width
;
319 internal int min_height
;
320 internal int max_width
;
321 internal int max_height
;
322 internal int base_width
;
323 internal int base_height
;
324 internal int width_inc
;
325 internal int height_inc
;
326 internal double min_aspect
;
327 internal double max_aspect
;
328 internal GdkGravity win_gravity
;
331 [StructLayout (LayoutKind
.Sequential
)]
332 internal struct GdkWindowAttr
{
333 internal string title
;
334 internal int event_mask
;
338 internal GdkWindowClass wclass
;
339 internal IntPtr visual
;
340 internal IntPtr colormap
;
341 internal GdkWindowType window_type
;
342 internal IntPtr cursor
;
343 internal string wmclass_name
;
344 internal string wmclass_class
;
345 internal bool override_redirect
;
348 #region Local Variables
350 static volatile XplatUIX11GTK Instance
;
351 private static int RefCount
;
352 private static object XlibLock
; // Our locking object
353 private static bool ThemesEnabled
;
356 private static IntPtr DisplayHandle
; // X11 handle to display
357 private static IntPtr GdkDisplayHandle
; // gdk handle to display
358 private static int ScreenNo
; // Screen number used
359 private static IntPtr GdkScreen
;
360 private static IntPtr DefaultColormap
; // Colormap for screen
361 private static IntPtr GdkDefaultColormap
; // Gdk Colormap for screen
362 private static IntPtr CustomVisual
; // Visual for window creation
363 private static IntPtr GdkCustomVisual
;
364 private static IntPtr CustomColormap
; // Colormap for window creation
365 private static IntPtr GdkCustomColormap
;
366 private static int VisualBestDepth
;
367 private static IntPtr RootWindow
; // Handle of the root window for the screen/display
368 private static IntPtr GdkRootWindow
; // Gdk handle of the root window for the screen/display
369 private static IntPtr FosterParent
; // Container to hold child windows until their parent exists
370 private static IntPtr GdkFosterParent
; // Container to hold child windows until their parent exists
371 private static XErrorHandler ErrorHandler
; // Error handler delegate
372 private static bool ErrorExceptions
; // Throw exceptions on X errors
373 private static bool PostQuitState
; // True if we've got an pending exit
376 private static IntPtr ClipMagic
= new IntPtr(27051977);
377 private static ClipboardStruct Clipboard
; // Our clipboard
380 private static int PostAtom
; // PostMessage atom
381 private static int AsyncAtom
; // Support for async messages
384 private static XEventQueue MessageQueue
; // Holds our queued up events
386 private static Pollfd
[] pollfds
; // For watching the X11 socket
388 private static X11Keyboard Keyboard
; //
389 private static X11Dnd Dnd
;
390 private static Socket listen
; //
391 private static Socket wake
; //
392 private static Socket wake_receive
; //
393 private static byte[] network_buffer
; //
397 private static IntPtr ActiveWindow
; // Handle of the active window
398 private static IntPtr FocusWindow
; // Handle of the window with keyboard focus (if any)
401 private static Stack ModalWindows
; // Stack of our modal windows
404 private static IntPtr SystrayMgrWindow
; // Handle of the Systray Manager window
407 private static IntPtr LastCursorWindow
; // The last window we set the cursor on
408 private static IntPtr LastCursorHandle
; // The handle that was last set on LastCursorWindow
409 private static IntPtr OverrideCursorHandle
; // The cursor that is set to override any other cursors
412 private static CaretStruct Caret
; //
414 // Support for Window Styles
415 private static int[] NetAtoms
; // All atoms we know
417 // mouse hover message generation
418 private static HoverStruct HoverState
; //
420 // double click message generation
421 private static ClickStruct ClickPending
; //
423 // Support for mouse grab
424 private static GrabStruct Grab
; //
427 private static Point MousePosition
; // Last position of mouse, in screen coords
428 internal static MouseButtons MouseState
; // Last state of mouse buttons
431 private static ArrayList TimerList
; // Holds SWF.Timers
434 private static int DoubleClickInterval
; // msec; max interval between clicks to count as double click
436 const GdkEventMask GdkSelectInputMask
= GdkEventMask
.GDK_BUTTON_PRESS_MASK
|
437 GdkEventMask
.GDK_BUTTON_RELEASE_MASK
|
438 GdkEventMask
.GDK_KEY_PRESS_MASK
|
439 GdkEventMask
.GDK_KEY_RELEASE_MASK
|
440 GdkEventMask
.GDK_ENTER_NOTIFY_MASK
|
441 GdkEventMask
.GDK_LEAVE_NOTIFY_MASK
|
442 GdkEventMask
.GDK_EXPOSURE_MASK
|
443 GdkEventMask
.GDK_FOCUS_CHANGE_MASK
|
444 GdkEventMask
.GDK_POINTER_MOTION_MASK
|
445 GdkEventMask
.GDK_VISIBILITY_NOTIFY_MASK
|
446 GdkEventMask
.GDK_SUBSTRUCTURE_MASK
|
447 GdkEventMask
.GDK_STRUCTURE_MASK
;
449 static readonly object lockobj
= new object ();
451 static Hashtable backing_store
= new Hashtable (5);
453 #endregion // Local Variables
455 private XplatUIX11GTK ()
457 Console
.WriteLine ("XplatUIX11GTK ctor...");
458 // Handle singleton stuff first
462 gdk_init_check (IntPtr
.Zero
, IntPtr
.Zero
);
464 // Now regular initialization
465 XlibLock
= new object ();
466 MessageQueue
= new XEventQueue ();
467 TimerList
= new ArrayList ();
470 ErrorExceptions
= false;
472 // X11 Initialization
473 SetDisplay (gdk_x11_display_get_xdisplay (gdk_display_get_default ()));
474 X11DesktopColors
.Initialize ();
476 // Handle any upcoming errors; we re-set it here, X11DesktopColor stuff might have stolen it (gtk does)
477 ErrorHandler
= new XErrorHandler (HandleError
);
478 XSetErrorHandler (ErrorHandler
);
480 #endregion // Constructors
482 #region Singleton Specific Code
483 public static XplatUIX11GTK
GetInstance ()
486 if (Instance
== null) {
487 Instance
= new XplatUIX11GTK ();
494 public int Reference
{
501 #region Internal Properties
502 internal static IntPtr Display
{
504 return DisplayHandle
;
508 XplatUIX11GTK
.GetInstance ().SetDisplay (value);
512 internal static int Screen
{
522 internal static IntPtr RootWindowHandle
{
532 internal static IntPtr Visual
{
538 CustomVisual
= value;
542 internal static IntPtr ColorMap
{
544 return CustomColormap
;
548 CustomColormap
= value;
553 #region XExceptionClass
554 internal class XException
: ApplicationException
{
558 XRequest RequestCode
;
562 public XException (IntPtr Display
, IntPtr ResourceID
, IntPtr Serial
, byte ErrorCode
, XRequest RequestCode
, byte MinorCode
)
564 this.Display
= Display
;
565 this.ResourceID
= ResourceID
;
566 this.Serial
= Serial
;
567 this.RequestCode
= RequestCode
;
568 this.ErrorCode
= ErrorCode
;
569 this.MinorCode
= MinorCode
;
572 public override string Message
{
574 return GetMessage (Display
, ResourceID
, Serial
, ErrorCode
, RequestCode
, MinorCode
);
578 public static string GetMessage (IntPtr Display
, IntPtr ResourceID
, IntPtr Serial
, byte ErrorCode
, XRequest RequestCode
, byte MinorCode
)
584 sb
= new StringBuilder (160);
585 XGetErrorText (Display
, ErrorCode
, sb
, sb
.Capacity
);
586 x_error_text
= sb
.ToString ();
588 error
= String
.Format ("\n Error: {0}\n Request: {1:D} ({2})\n Resource ID: 0x{3:x}\n Serial: {4}", x_error_text
, RequestCode
, RequestCode
, ResourceID
.ToInt32 (), Serial
);
592 #endregion // XExceptionClass
594 #region Internal Methods
595 // native X display handle
596 internal void SetDisplay (IntPtr display_handle
)
598 if (display_handle
!= IntPtr
.Zero
) {
601 if ((GdkDisplayHandle
!= IntPtr
.Zero
) && (GdkFosterParent
!= IntPtr
.Zero
)) {
602 hwnd
= Hwnd
.ObjectFromHandle (gdk_x11_drawable_get_xid (GdkFosterParent
));
603 gdk_window_destroy (GdkFosterParent
);
607 if (GdkDisplayHandle
!= IntPtr
.Zero
) {
608 gdk_display_close (GdkDisplayHandle
);
611 DisplayHandle
= display_handle
;
612 GdkDisplayHandle
= gdk_x11_lookup_xdisplay (display_handle
);
614 // We need to tell System.Drawing our DisplayHandle. FromHdcInternal has
615 // been hacked to do this for us.
616 Graphics
.FromHdcInternal (DisplayHandle
);
619 if (Environment
.GetEnvironmentVariable ("MONO_XSYNC") != null) {
620 XSynchronize (DisplayHandle
, true);
623 if (Environment
.GetEnvironmentVariable ("MONO_XEXCEPTIONS") != null) {
624 ErrorExceptions
= true;
628 GdkScreen
= gdk_screen_get_default ();
629 // or gdk_x11_get_default_screen
630 ScreenNo
= gdk_screen_get_number (GdkScreen
);
631 GdkRootWindow
= gdk_get_default_root_window ();
632 RootWindow
= gdk_x11_drawable_get_xid (GdkRootWindow
);
633 GdkDefaultColormap
= gdk_colormap_get_system ();
634 DefaultColormap
= gdk_x11_colormap_get_xcolormap (GdkDefaultColormap
);
636 VisualBestDepth
= gdk_visual_get_best_depth ();
637 //Console.WriteLine (VisualBestDepth);
639 // Create the foster parent
640 FosterParent
= XCreateSimpleWindow (DisplayHandle
, RootWindow
, 0, 0, 1, 1, 4, 0, 0);
641 GdkFosterParent
= gdk_window_foreign_new (FosterParent
);
643 if (GdkFosterParent
== IntPtr
.Zero
) {
644 Console
.WriteLine ("XplatUIX11GTK Constructor failed to create FosterParent");
649 hwnd
.WholeWindow
= FosterParent
;
650 hwnd
.ClientWindow
= FosterParent
;
652 // For sleeping on the X11 socket
653 listen
= new Socket (AddressFamily
.InterNetwork
, SocketType
.Stream
, ProtocolType
.IP
);
654 IPEndPoint ep
= new IPEndPoint (IPAddress
.Loopback
, 0);
658 // To wake up when a timer is ready
659 network_buffer
= new byte [10];
661 wake
= new Socket (AddressFamily
.InterNetwork
, SocketType
.Stream
, ProtocolType
.IP
);
662 wake
.Connect (listen
.LocalEndPoint
);
663 wake_receive
= listen
.Accept ();
666 pollfds
= new Pollfd
[2];
667 pollfds
[0] = new Pollfd ();
668 pollfds
[0].fd
= XConnectionNumber (DisplayHandle
);
669 pollfds
[0].events
= PollEvents
.POLLIN
;
671 pollfds
[1] = new Pollfd ();
672 pollfds
[1].fd
= wake_receive
.Handle
.ToInt32 ();
673 pollfds
[1].events
= PollEvents
.POLLIN
;
676 Keyboard
= new X11Keyboard (DisplayHandle
);
677 Dnd
= new X11Dnd (DisplayHandle
);
679 PostQuitState
= false;
681 DoubleClickInterval
= 500;
683 HoverState
.Interval
= 500;
684 HoverState
.Timer
= new Timer ();
685 HoverState
.Timer
.Enabled
= false;
686 HoverState
.Timer
.Interval
= HoverState
.Interval
;
687 HoverState
.Timer
.Tick
+= new EventHandler (MouseHover
);
691 ActiveWindow
= IntPtr
.Zero
;
692 FocusWindow
= IntPtr
.Zero
;
693 ModalWindows
= new Stack (3);
695 MouseState
= MouseButtons
.None
;
696 MousePosition
= new Point (0, 0);
698 Caret
.Timer
= new Timer ();
699 Caret
.Timer
.Interval
= 500; // FIXME - where should this number come from?
700 Caret
.Timer
.Tick
+= new EventHandler (CaretCallback
);
704 // Grab atom changes off the root window to catch certain WM events
705 gdk_window_set_events (GdkRootWindow
, (int)GdkEventMask
.GDK_PROPERTY_CHANGE_MASK
);
707 // Handle any upcoming errors
708 ErrorHandler
= new XErrorHandler (HandleError
);
709 XSetErrorHandler (ErrorHandler
);
711 throw new ArgumentNullException ("Display", "Could not open display (X-Server required. Check you DISPLAY environment variable)");
714 #endregion // Internal Methods
716 #region Private Methods
717 private static void SetupAtoms ()
719 NetAtoms
= new int [(int)NA
.LAST_NET_ATOM
];
721 NetAtoms
[(int)NA
.WM_PROTOCOLS
] = XInternAtom (DisplayHandle
, "WM_PROTOCOLS", false);
722 NetAtoms
[(int)NA
.WM_DELETE_WINDOW
] = XInternAtom (DisplayHandle
, "WM_DELETE_WINDOW", false);
723 NetAtoms
[(int)NA
.WM_TAKE_FOCUS
] = XInternAtom (DisplayHandle
, "WM_TAKE_FOCUS", false);
725 NetAtoms
[(int)NA
._NET_SUPPORTED
] = XInternAtom (DisplayHandle
, "_NET_SUPPORTED", false);
726 NetAtoms
[(int)NA
._NET_CLIENT_LIST
] = XInternAtom (DisplayHandle
, "_NET_CLIENT_LIST", false);
727 NetAtoms
[(int)NA
._NET_NUMBER_OF_DESKTOPS
] = XInternAtom (DisplayHandle
, "_NET_NUMBER_OF_DESKTOPS", false);
728 NetAtoms
[(int)NA
._NET_DESKTOP_GEOMETRY
] = XInternAtom (DisplayHandle
, "_NET_DESKTOP_GEOMETRY", false);
729 NetAtoms
[(int)NA
._NET_DESKTOP_VIEWPORT
] = XInternAtom (DisplayHandle
, "_NET_DESKTOP_VIEWPORT", false);
730 NetAtoms
[(int)NA
._NET_CURRENT_DESKTOP
] = XInternAtom (DisplayHandle
, "_NET_CURRENT_DESKTOP", false);
731 NetAtoms
[(int)NA
._NET_DESKTOP_NAMES
] = XInternAtom (DisplayHandle
, "_NET_DESKTOP_NAMES", false);
732 NetAtoms
[(int)NA
._NET_ACTIVE_WINDOW
] = XInternAtom (DisplayHandle
, "_NET_ACTIVE_WINDOW", false);
733 NetAtoms
[(int)NA
._NET_WORKAREA
] = XInternAtom (DisplayHandle
, "_NET_WORKAREA", false);
734 NetAtoms
[(int)NA
._NET_SUPPORTING_WM_CHECK
] = XInternAtom (DisplayHandle
, "_NET_SUPPORTING_WM_CHECK", false);
735 NetAtoms
[(int)NA
._NET_VIRTUAL_ROOTS
] = XInternAtom (DisplayHandle
, "_NET_VIRTUAL_ROOTS", false);
736 NetAtoms
[(int)NA
._NET_DESKTOP_LAYOUT
] = XInternAtom (DisplayHandle
, "_NET_DESKTOP_LAYOUT", false);
737 NetAtoms
[(int)NA
._NET_SHOWING_DESKTOP
] = XInternAtom (DisplayHandle
, "_NET_SHOWING_DESKTOP", false);
739 NetAtoms
[(int)NA
._NET_CLOSE_WINDOW
] = XInternAtom (DisplayHandle
, "_NET_CLOSE_WINDOW", false);
740 NetAtoms
[(int)NA
._NET_MOVERESIZE_WINDOW
] = XInternAtom (DisplayHandle
, "_NET_MOVERESIZE_WINDOW", false);
741 NetAtoms
[(int)NA
._NET_WM_MOVERESIZE
] = XInternAtom (DisplayHandle
, "_NET_WM_MOVERESIZE", false);
742 NetAtoms
[(int)NA
._NET_RESTACK_WINDOW
] = XInternAtom (DisplayHandle
, "_NET_RESTACK_WINDOW", false);
743 NetAtoms
[(int)NA
._NET_REQUEST_FRAME_EXTENTS
] = XInternAtom (DisplayHandle
, "_NET_REQUEST_FRAME_EXTENTS", false);
745 NetAtoms
[(int)NA
._NET_WM_NAME
] = XInternAtom (DisplayHandle
, "_NET_WM_NAME", false);
746 NetAtoms
[(int)NA
._NET_WM_VISIBLE_NAME
] = XInternAtom (DisplayHandle
, "_NET_WM_VISIBLE_NAME", false);
747 NetAtoms
[(int)NA
._NET_WM_ICON_NAME
] = XInternAtom (DisplayHandle
, "_NET_WM_ICON_NAME", false);
748 NetAtoms
[(int)NA
._NET_WM_VISIBLE_ICON_NAME
] = XInternAtom (DisplayHandle
, "_NET_WM_VISIBLE_ICON_NAME", false);
749 NetAtoms
[(int)NA
._NET_WM_DESKTOP
] = XInternAtom (DisplayHandle
, "_NET_WM_DESKTOP", false);
750 NetAtoms
[(int)NA
._NET_WM_WINDOW_TYPE
] = XInternAtom (DisplayHandle
, "_NET_WM_WINDOW_TYPE", false);
751 NetAtoms
[(int)NA
._NET_WM_STATE
] = XInternAtom (DisplayHandle
, "_NET_WM_STATE", false);
752 NetAtoms
[(int)NA
._NET_WM_ALLOWED_ACTIONS
] = XInternAtom (DisplayHandle
, "_NET_WM_ALLOWED_ACTIONS", false);
753 NetAtoms
[(int)NA
._NET_WM_STRUT
] = XInternAtom (DisplayHandle
, "_NET_WM_STRUT", false);
754 NetAtoms
[(int)NA
._NET_WM_STRUT_PARTIAL
] = XInternAtom (DisplayHandle
, "_NET_WM_STRUT_PARTIAL", false);
755 NetAtoms
[(int)NA
._NET_WM_ICON_GEOMETRY
] = XInternAtom (DisplayHandle
, "_NET_WM_ICON_GEOMETRY", false);
756 NetAtoms
[(int)NA
._NET_WM_ICON
] = XInternAtom (DisplayHandle
, "_NET_WM_ICON", false);
757 NetAtoms
[(int)NA
._NET_WM_PID
] = XInternAtom (DisplayHandle
, "_NET_WM_PID", false);
758 NetAtoms
[(int)NA
._NET_WM_HANDLED_ICONS
] = XInternAtom (DisplayHandle
, "_NET_WM_HANDLED_ICONS", false);
759 NetAtoms
[(int)NA
._NET_WM_USER_TIME
] = XInternAtom (DisplayHandle
, "_NET_WM_USER_TIME", false);
760 NetAtoms
[(int)NA
._NET_FRAME_EXTENTS
] = XInternAtom (DisplayHandle
, "_NET_FRAME_EXTENTS", false);
762 NetAtoms
[(int)NA
._NET_WM_PING
] = XInternAtom (DisplayHandle
, "_NET_WM_PING", false);
763 NetAtoms
[(int)NA
._NET_WM_SYNC_REQUEST
] = XInternAtom (DisplayHandle
, "_NET_WM_SYNC_REQUEST", false);
765 NetAtoms
[(int)NA
._NET_SYSTEM_TRAY_S
] = XInternAtom (DisplayHandle
, "_NET_SYSTEM_TRAY_S" + ScreenNo
.ToString (), false);
766 NetAtoms
[(int)NA
._NET_SYSTEM_TRAY_OPCODE
] = XInternAtom (DisplayHandle
, "_NET_SYSTEM_TRAY_OPCODE", false);
767 NetAtoms
[(int)NA
._NET_SYSTEM_TRAY_ORIENTATION
] = XInternAtom (DisplayHandle
, "_NET_SYSTEM_TRAY_ORIENTATION", false);
769 NetAtoms
[(int)NA
._NET_WM_STATE_MAXIMIZED_HORZ
] = XInternAtom (DisplayHandle
, "_NET_WM_STATE_MAXIMIZED_HORZ", false);
770 NetAtoms
[(int)NA
._NET_WM_STATE_MAXIMIZED_VERT
] = XInternAtom (DisplayHandle
, "_NET_WM_STATE_MAXIMIZED_VERT", false);
771 NetAtoms
[(int)NA
._NET_WM_STATE_HIDDEN
] = XInternAtom (DisplayHandle
, "_NET_WM_STATE_HIDDEN", false);
773 NetAtoms
[(int)NA
._XEMBED
] = XInternAtom (DisplayHandle
, "_XEMBED", false);
774 NetAtoms
[(int)NA
._XEMBED_INFO
] = XInternAtom (DisplayHandle
, "_XEMBED_INFO", false);
776 NetAtoms
[(int)NA
._MOTIF_WM_HINTS
] = XInternAtom (DisplayHandle
, "_MOTIF_WM_HINTS", false);
778 NetAtoms
[(int)NA
._NET_WM_STATE_NO_TASKBAR
] = XInternAtom (DisplayHandle
, "_NET_WM_STATE_NO_TASKBAR", false);
779 NetAtoms
[(int)NA
._NET_WM_STATE_ABOVE
] = XInternAtom (DisplayHandle
, "_NET_WM_STATE_ABOVE", false);
780 NetAtoms
[(int)NA
._NET_WM_STATE_MODAL
] = XInternAtom (DisplayHandle
, "_NET_WM_STATE_MODAL", false);
781 NetAtoms
[(int)NA
._NET_WM_CONTEXT_HELP
] = XInternAtom (DisplayHandle
, "_NET_WM_CONTEXT_HELP", false);
782 NetAtoms
[(int)NA
._NET_WM_WINDOW_OPACITY
] = XInternAtom (DisplayHandle
, "_NET_WM_WINDOW_OPACITY", false);
785 NetAtoms
[(int)NA
.CLIPBOARD
] = XInternAtom (DisplayHandle
, "CLIPBOARD", false);
786 NetAtoms
[(int)NA
.DIB
] = (int)Atom
.XA_PIXMAP
;
787 NetAtoms
[(int)NA
.OEMTEXT
] = XInternAtom (DisplayHandle
, "COMPOUND_TEXT", false);
788 NetAtoms
[(int)NA
.UNICODETEXT
] = XInternAtom (DisplayHandle
, "UTF8_STRING", false);
789 NetAtoms
[(int)NA
.TARGETS
] = XInternAtom (DisplayHandle
, "TARGETS", false);
792 AsyncAtom
= XInternAtom (DisplayHandle
, "_SWF_AsyncAtom", false);
793 PostAtom
= XInternAtom (DisplayHandle
, "_SWF_PostMessageAtom", false);
794 HoverState
.Atom
= XInternAtom (DisplayHandle
, "_SWF_HoverAtom", false);
797 private void GetSystrayManagerWindow ()
799 gdk_x11_grab_server ();
800 SystrayMgrWindow
= XGetSelectionOwner (DisplayHandle
, NetAtoms
[(int)NA
._NET_SYSTEM_TRAY_S
]);
801 gdk_x11_ungrab_server ();
802 gdk_display_flush (GdkDisplayHandle
);
805 private void SendNetWMMessage (IntPtr window
, IntPtr message_type
, IntPtr l0
, IntPtr l1
, IntPtr l2
)
810 xev
.ClientMessageEvent
.type
= XEventName
.ClientMessage
;
811 xev
.ClientMessageEvent
.send_event
= true;
812 xev
.ClientMessageEvent
.window
= window
;
813 xev
.ClientMessageEvent
.message_type
= message_type
;
814 xev
.ClientMessageEvent
.format
= 32;
815 xev
.ClientMessageEvent
.ptr1
= l0
;
816 xev
.ClientMessageEvent
.ptr2
= l1
;
817 xev
.ClientMessageEvent
.ptr3
= l2
;
818 XSendEvent (DisplayHandle
, RootWindow
, false, EventMask
.SubstructureRedirectMask
| EventMask
.SubstructureNotifyMask
, ref xev
);
821 private void SendNetClientMessage (IntPtr window
, IntPtr message_type
, IntPtr l0
, IntPtr l1
, IntPtr l2
)
826 xev
.ClientMessageEvent
.type
= XEventName
.ClientMessage
;
827 xev
.ClientMessageEvent
.send_event
= true;
828 xev
.ClientMessageEvent
.window
= window
;
829 xev
.ClientMessageEvent
.message_type
= message_type
;
830 xev
.ClientMessageEvent
.format
= 32;
831 xev
.ClientMessageEvent
.ptr1
= l0
;
832 xev
.ClientMessageEvent
.ptr2
= l1
;
833 xev
.ClientMessageEvent
.ptr3
= l2
;
834 XSendEvent (DisplayHandle
, window
, false, EventMask
.NoEventMask
, ref xev
);
837 private void DeriveStyles (IntPtr handle
, int Style
, int ExStyle
, out FormBorderStyle border_style
, out TitleStyle title_style
, out int caption_height
, out int tool_caption_height
)
840 // Only MDI windows get caption_heights
842 tool_caption_height
= 19;
844 if ((Style
& (int) WindowStyles
.WS_CHILD
) != 0) {
845 if ((Style
& (int) WindowStyles
.WS_BORDER
) == 0) {
846 border_style
= FormBorderStyle
.None
;
847 } else if ((ExStyle
& (int) WindowStyles
.WS_EX_CLIENTEDGE
) != 0) {
848 border_style
= FormBorderStyle
.Fixed3D
;
850 border_style
= FormBorderStyle
.FixedSingle
;
852 title_style
= TitleStyle
.None
;
856 if ((ExStyle
& (int) WindowStyles
.WS_EX_MDICHILD
) != 0) {
861 title_style
= TitleStyle
.None
;
862 if ((Style
& (int)WindowStyles
.WS_CAPTION
) != 0) {
863 if ((ExStyle
& (int)WindowStyles
.WS_EX_TOOLWINDOW
) != 0) {
864 title_style
= TitleStyle
.Tool
;
866 title_style
= TitleStyle
.Normal
;
871 border_style
= FormBorderStyle
.None
;
873 if ((Style
& (int)WindowStyles
.WS_THICKFRAME
) != 0) {
874 if ((ExStyle
& (int)WindowStyles
.WS_EX_TOOLWINDOW
) != 0) {
875 border_style
= FormBorderStyle
.SizableToolWindow
;
877 border_style
= FormBorderStyle
.Sizable
;
880 if ((ExStyle
& (int)WindowStyles
.WS_EX_CLIENTEDGE
) != 0) {
881 border_style
= FormBorderStyle
.Fixed3D
;
882 } else if ((ExStyle
& (int)WindowStyles
.WS_EX_DLGMODALFRAME
) != 0) {
883 border_style
= FormBorderStyle
.FixedDialog
;
884 } else if ((ExStyle
& (int)WindowStyles
.WS_EX_TOOLWINDOW
) != 0) {
885 border_style
= FormBorderStyle
.FixedToolWindow
;
886 } else if ((Style
& (int)WindowStyles
.WS_BORDER
) != 0) {
887 border_style
= FormBorderStyle
.Sizable
;
889 border_style
= FormBorderStyle
.None
;
893 if ((Style
& (int) WindowStyles
.WS_OVERLAPPEDWINDOW
) != 0 ||
894 (ExStyle
& (int) WindowStyles
.WS_EX_TOOLWINDOW
) != 0) {
895 border_style
= (FormBorderStyle
) 0xFFFF;
897 border_style
= FormBorderStyle
.None
;
903 private void SetHwndStyles (Hwnd hwnd
, CreateParams cp
)
905 DeriveStyles (hwnd
.Handle
, cp
.Style
, cp
.ExStyle
, out hwnd
.border_style
, out hwnd
.title_style
, out hwnd
.caption_height
, out hwnd
.tool_caption_height
);
908 private void SetWMStyles (Hwnd hwnd
, CreateParams cp
)
910 GdkWMDecoration decorations
= GdkWMDecoration
.GDK_DECOR_ALL
;
912 if ((cp
.Style
& (int)WindowStyles
.WS_CAPTION
) != 0) {
913 decorations
|= GdkWMDecoration
.GDK_DECOR_TITLE
| GdkWMDecoration
.GDK_DECOR_MENU
;
916 if ((cp
.Style
& ((int)WindowStyles
.WS_THICKFRAME
)) != 0) {
917 decorations
|= GdkWMDecoration
.GDK_DECOR_BORDER
| GdkWMDecoration
.GDK_DECOR_RESIZEH
;
919 if ((cp
.Style
& ((int)WindowStyles
.WS_MINIMIZEBOX
)) != 0) {
920 decorations
|= GdkWMDecoration
.GDK_DECOR_MINIMIZE
;
923 if ((cp
.Style
& ((int)WindowStyles
.WS_MAXIMIZEBOX
)) != 0) {
924 decorations
|= GdkWMDecoration
.GDK_DECOR_MAXIMIZE
;
927 // is this needed ? most window managers do not even honour any MotifFunctions...
928 // if ((cp.Style & ((int)WindowStyles.WS_SYSMENU)) != 0) {
929 // functions |= MotifFunctions.Close;
932 if ((cp
.ExStyle
& ((int)WindowStyles
.WS_EX_DLGMODALFRAME
)) != 0) {
933 decorations
|= GdkWMDecoration
.GDK_DECOR_BORDER
;
936 if ((cp
.Style
& ((int)WindowStyles
.WS_DLGFRAME
)) != 0) {
937 decorations
|= GdkWMDecoration
.GDK_DECOR_BORDER
;
940 if ((cp
.Style
& ((int)WindowStyles
.WS_BORDER
)) != 0) {
941 decorations
|= GdkWMDecoration
.GDK_DECOR_BORDER
;
944 if ((cp
.ExStyle
& ((int)WindowStyles
.WS_EX_TOOLWINDOW
)) != 0) {
948 gdk_window_set_decorations (gdk_window_foreign_new (hwnd
.whole_window
), (int)decorations
);
951 private void SetIcon (Hwnd hwnd
, Icon icon
)
958 bitmap
= icon
.ToBitmap ();
960 size
= bitmap
.Width
* bitmap
.Height
+ 2;
961 data
= new uint [size
];
963 data
[index
++] = (uint)bitmap
.Width
;
964 data
[index
++] = (uint)bitmap
.Height
;
966 for (int y
= 0; y
< bitmap
.Height
; y
++) {
967 for (int x
= 0; x
< bitmap
.Width
; x
++) {
968 data
[index
++] = (uint)bitmap
.GetPixel (x
, y
).ToArgb ();
971 XChangeProperty (DisplayHandle
, hwnd
.whole_window
, NetAtoms
[(int)NA
._NET_WM_ICON
], Atom
.XA_CARDINAL
, 32, PropertyMode
.Replace
, data
, size
);
974 private IntPtr
ImageToPixmap (Image image
)
979 private void WakeupMain ()
981 wake
.Send (new byte [] { 0xFF }
);
984 private void TranslatePropertyToClipboard (int property
)
990 IntPtr prop
= IntPtr
.Zero
;
992 Clipboard
.Item
= null;
994 XGetWindowProperty (DisplayHandle
, FosterParent
, property
, 0, 0x7fffffff, true, Atom
.AnyPropertyType
, out actual_atom
, out actual_format
, out nitems
, out bytes_after
, ref prop
);
997 if (property
== (int)Atom
.XA_STRING
) {
998 Clipboard
.Item
= Marshal
.PtrToStringAnsi (prop
);
999 } else if (property
== (int)Atom
.XA_BITMAP
) {
1000 // FIXME - convert bitmap to image
1001 } else if (property
== (int)Atom
.XA_PIXMAP
) {
1002 // FIXME - convert pixmap to image
1003 } else if (property
== NetAtoms
[(int)NA
.OEMTEXT
]) {
1004 Clipboard
.Item
= Marshal
.PtrToStringAnsi (prop
);
1005 } else if (property
== NetAtoms
[(int)NA
.UNICODETEXT
]) {
1006 Clipboard
.Item
= Marshal
.PtrToStringAnsi (prop
);
1013 private void AddExpose (XEvent xevent
)
1017 hwnd
= Hwnd
.GetObjectFromWindow (xevent
.AnyEvent
.window
);
1024 if (xevent
.AnyEvent
.window
== hwnd
.client_window
) {
1025 hwnd
.AddInvalidArea (xevent
.ExposeEvent
.x
, xevent
.ExposeEvent
.y
, xevent
.ExposeEvent
.width
, xevent
.ExposeEvent
.height
);
1026 if (!hwnd
.expose_pending
) {
1027 MessageQueue
.Enqueue (xevent
);
1028 hwnd
.expose_pending
= true;
1031 if (!hwnd
.nc_expose_pending
) {
1032 MessageQueue
.Enqueue (xevent
);
1033 hwnd
.nc_expose_pending
= true;
1038 private void InvalidateWholeWindow (IntPtr handle
)
1042 hwnd
= Hwnd
.ObjectFromHandle (handle
);
1044 InvalidateWholeWindow (handle
, new Rectangle (0, 0, hwnd
.Width
, hwnd
.Height
));
1047 private void InvalidateWholeWindow (IntPtr handle
, Rectangle rectangle
)
1052 hwnd
= Hwnd
.ObjectFromHandle (handle
);
1055 xevent
= new XEvent ();
1056 xevent
.type
= XEventName
.Expose
;
1057 xevent
.ExposeEvent
.display
= DisplayHandle
;
1058 xevent
.ExposeEvent
.window
= hwnd
.whole_window
;
1060 xevent
.ExposeEvent
.x
= rectangle
.X
;
1061 xevent
.ExposeEvent
.y
= rectangle
.Y
;
1062 xevent
.ExposeEvent
.width
= rectangle
.Width
;
1063 xevent
.ExposeEvent
.height
= rectangle
.Height
;
1068 private void WholeToScreen (IntPtr handle
, ref int x
, ref int y
)
1074 hwnd
= Hwnd
.ObjectFromHandle (handle
);
1077 gdk_window_get_origin (gdk_window_lookup (hwnd
.whole_window
), out dest_x_return
, out dest_y_return
);
1084 private void AddConfigureNotify (XEvent xevent
)
1088 hwnd
= Hwnd
.GetObjectFromWindow (xevent
.ConfigureEvent
.window
);
1095 if (xevent
.ConfigureEvent
.window
== hwnd
.whole_window
) {
1096 if (!hwnd
.reparented
) {
1097 hwnd
.x
= xevent
.ConfigureEvent
.x
;
1098 hwnd
.y
= xevent
.ConfigureEvent
.y
;
1102 gdk_window_get_geometry (gdk_window_lookup (hwnd
.whole_window
), out hwnd
.x
, out hwnd
.y
, out dummy_int
, out dummy_int
, out dummy_int
);
1105 hwnd
.width
= xevent
.ConfigureEvent
.width
;
1106 hwnd
.height
= xevent
.ConfigureEvent
.height
;
1108 if (!hwnd
.configure_pending
) {
1109 MessageQueue
.Enqueue (xevent
);
1110 hwnd
.configure_pending
= true;
1113 // We drop configure events for Client windows
1116 private void ShowCaret ()
1118 if ((Caret
.gc
== IntPtr
.Zero
) || Caret
.On
) {
1123 // gdk_gc_set_foreground
1126 XDrawLine (DisplayHandle
, Caret
.Window
, Caret
.gc
, Caret
.X
, Caret
.Y
, Caret
.X
, Caret
.Y
+ Caret
.Height
);
1130 private void HideCaret ()
1132 if ((Caret
.gc
== IntPtr
.Zero
) || !Caret
.On
) {
1137 // gdk_gc_set_foreground
1140 XDrawLine (DisplayHandle
, Caret
.Window
, Caret
.gc
, Caret
.X
, Caret
.Y
, Caret
.X
, Caret
.Y
+ Caret
.Height
);
1144 private int NextTimeout (DateTime now
)
1146 int timeout
= Int32
.MaxValue
;
1148 foreach (Timer timer
in TimerList
) {
1149 int next
= (int) (timer
.Expires
- now
).TotalMilliseconds
;
1151 return 0; // Have a timer that has already expired
1154 if (next
< timeout
) {
1159 if (timeout
< Timer
.Minimum
) {
1160 timeout
= Timer
.Minimum
;
1166 private void CheckTimers (DateTime now
)
1171 count
= TimerList
.Count
;
1177 for (int i
= 0; i
< TimerList
.Count
; i
++) {
1180 timer
= (Timer
) TimerList
[i
];
1182 if (timer
.Enabled
&& timer
.Expires
<= now
) {
1190 private void UpdateMessageQueue ()
1198 pending
= XPending (DisplayHandle
);
1203 Idle (this, EventArgs
.Empty
);
1207 pending
= XPending (DisplayHandle
);
1214 timeout
= NextTimeout (now
);
1217 Syscall
.poll (pollfds
, (uint) pollfds
.Length
, timeout
);
1218 // Clean out buffer, so we're not busy-looping on the same data
1219 if (pollfds
[1].revents
!= 0) {
1220 wake_receive
.Receive(network_buffer
, 0, 1, SocketFlags
.None
);
1224 pending
= XPending (DisplayHandle
);
1233 pending
= XPending (DisplayHandle
);
1237 while (pending
> 0) {
1238 XEvent xevent
= new XEvent ();
1241 XNextEvent (DisplayHandle
, ref xevent
);
1243 //Console.WriteLine("Got x event {0}", xevent);
1244 switch (xevent
.type
) {
1245 case XEventName
.Expose
:
1249 case XEventName
.SelectionClear
: {
1250 // Should we do something?
1254 case XEventName
.SelectionRequest
: {
1255 if (Dnd
.HandleSelectionRequestEvent (ref xevent
))
1259 sel_event
= new XEvent ();
1260 sel_event
.SelectionEvent
.type
= XEventName
.SelectionNotify
;
1261 sel_event
.SelectionEvent
.send_event
= true;
1262 sel_event
.SelectionEvent
.display
= DisplayHandle
;
1263 sel_event
.SelectionEvent
.selection
= xevent
.SelectionRequestEvent
.selection
;
1264 sel_event
.SelectionEvent
.target
= xevent
.SelectionRequestEvent
.target
;
1265 sel_event
.SelectionEvent
.requestor
= xevent
.SelectionRequestEvent
.requestor
;
1266 sel_event
.SelectionEvent
.time
= xevent
.SelectionRequestEvent
.time
;
1267 sel_event
.SelectionEvent
.property
= 0;
1269 // Seems that some apps support asking for supported types
1270 if (xevent
.SelectionEvent
.target
== NetAtoms
[(int)NA
.TARGETS
]) {
1274 atoms
= new uint [5];
1277 if (Clipboard
.Item
is String
) {
1278 atoms
[atom_count
++] = (uint)Atom
.XA_STRING
;
1279 atoms
[atom_count
++] = (uint)NetAtoms
[(int)NA
.OEMTEXT
];
1280 atoms
[atom_count
++] = (uint)NetAtoms
[(int)NA
.UNICODETEXT
];
1281 } else if (Clipboard
.Item
is Image
) {
1282 atoms
[atom_count
++] = (uint)Atom
.XA_PIXMAP
;
1283 atoms
[atom_count
++] = (uint)Atom
.XA_BITMAP
;
1285 // FIXME - handle other types
1288 XChangeProperty (DisplayHandle
, xevent
.SelectionEvent
.requestor
, xevent
.SelectionRequestEvent
.property
, xevent
.SelectionRequestEvent
.target
, 32, PropertyMode
.Replace
, atoms
, atom_count
);
1289 } else if (Clipboard
.Item
is string) {
1295 if (xevent
.SelectionRequestEvent
.target
== (int)Atom
.XA_STRING
) {
1298 bytes
= new ASCIIEncoding ().GetBytes ((string)Clipboard
.Item
);
1299 buffer
= Marshal
.AllocHGlobal (bytes
.Length
);
1300 buflen
= bytes
.Length
;
1302 for (int i
= 0; i
< buflen
; i
++) {
1303 Marshal
.WriteByte (buffer
, i
, bytes
[i
]);
1305 } else if (xevent
.SelectionRequestEvent
.target
== NetAtoms
[(int)NA
.OEMTEXT
]) {
1306 // FIXME - this should encode into ISO2022
1307 buffer
= Marshal
.StringToHGlobalAnsi ((string)Clipboard
.Item
);
1308 while (Marshal
.ReadByte (buffer
, buflen
) != 0) {
1311 } else if (xevent
.SelectionRequestEvent
.target
== NetAtoms
[(int)NA
.UNICODETEXT
]) {
1312 buffer
= Marshal
.StringToHGlobalAnsi ((string)Clipboard
.Item
);
1313 while (Marshal
.ReadByte (buffer
, buflen
) != 0) {
1317 buffer
= IntPtr
.Zero
;
1320 if (buffer
!= IntPtr
.Zero
) {
1321 XChangeProperty (DisplayHandle
, xevent
.SelectionRequestEvent
.requestor
, xevent
.SelectionRequestEvent
.property
, xevent
.SelectionRequestEvent
.target
, 8, PropertyMode
.Replace
, buffer
, buflen
);
1322 sel_event
.SelectionEvent
.property
= xevent
.SelectionRequestEvent
.property
;
1323 Marshal
.FreeHGlobal (buffer
);
1325 } else if (Clipboard
.Item
is Image
) {
1326 if (xevent
.SelectionEvent
.target
== (int)Atom
.XA_PIXMAP
) {
1327 // FIXME - convert image and store as property
1328 } else if (xevent
.SelectionEvent
.target
== (int)Atom
.XA_PIXMAP
) {
1329 // FIXME - convert image and store as property
1333 XSendEvent (DisplayHandle
, xevent
.SelectionRequestEvent
.requestor
, false, EventMask
.NoEventMask
, ref sel_event
);
1337 case XEventName
.SelectionNotify
: {
1338 if (Clipboard
.Enumerating
) {
1339 Clipboard
.Enumerating
= false;
1340 if (xevent
.SelectionEvent
.property
!= 0) {
1341 XDeleteProperty (DisplayHandle
, FosterParent
, xevent
.SelectionEvent
.property
);
1342 if (!Clipboard
.Formats
.Contains (xevent
.SelectionEvent
.property
)) {
1343 Clipboard
.Formats
.Add (xevent
.SelectionEvent
.property
);
1344 #if DriverDebugExtra
1345 Console
.WriteLine("Got supported clipboard atom format: {0}", xevent
.SelectionEvent
.property
);
1349 } else if (Clipboard
.Retrieving
) {
1350 Clipboard
.Retrieving
= false;
1351 if (xevent
.SelectionEvent
.property
!= 0) {
1352 TranslatePropertyToClipboard (xevent
.SelectionEvent
.property
);
1354 Clipboard
.Item
= null;
1357 Dnd
.HandleSelectionNotifyEvent (ref xevent
);
1362 case XEventName
.KeyPress
:
1363 case XEventName
.KeyRelease
:
1364 case XEventName
.ButtonPress
:
1365 case XEventName
.ButtonRelease
:
1366 case XEventName
.MotionNotify
:
1367 case XEventName
.EnterNotify
:
1368 case XEventName
.LeaveNotify
:
1369 case XEventName
.CreateNotify
:
1370 case XEventName
.DestroyNotify
:
1371 case XEventName
.FocusIn
:
1372 case XEventName
.FocusOut
:
1373 case XEventName
.ClientMessage
:
1374 case XEventName
.ReparentNotify
:
1375 MessageQueue
.Enqueue (xevent
);
1378 case XEventName
.ConfigureNotify
:
1379 AddConfigureNotify (xevent
);
1382 case XEventName
.PropertyNotify
:
1383 if (xevent
.PropertyEvent
.atom
== NetAtoms
[(int)NA
._NET_ACTIVE_WINDOW
]) {
1388 IntPtr prop
= IntPtr
.Zero
;
1389 IntPtr prev_active
;;
1391 prev_active
= ActiveWindow
;
1392 XGetWindowProperty (DisplayHandle
, RootWindow
, NetAtoms
[(int)NA
._NET_ACTIVE_WINDOW
], 0, 1, false, Atom
.XA_WINDOW
, out actual_atom
, out actual_format
, out nitems
, out bytes_after
, ref prop
);
1393 if ((nitems
> 0) && (prop
!= IntPtr
.Zero
)) {
1394 ActiveWindow
= Hwnd
.GetHandleFromWindow ((IntPtr
)Marshal
.ReadInt32 (prop
));
1397 if (prev_active
!= ActiveWindow
) {
1398 if (prev_active
!= IntPtr
.Zero
) {
1399 PostMessage (prev_active
, Msg
.WM_ACTIVATE
, (IntPtr
)WindowActiveFlags
.WA_INACTIVE
, IntPtr
.Zero
);
1401 if (ActiveWindow
!= IntPtr
.Zero
) {
1402 PostMessage (ActiveWindow
, Msg
.WM_ACTIVATE
, (IntPtr
)WindowActiveFlags
.WA_ACTIVE
, IntPtr
.Zero
);
1405 if (ModalWindows
.Count
== 0) {
1408 // Modality handling, if we are modal and the new active window is one
1409 // of ours but not the modal one, switch back to the modal window
1411 if (NativeWindow
.FindWindow (ActiveWindow
) != null) {
1412 if (ActiveWindow
!= (IntPtr
)ModalWindows
.Peek ()) {
1413 Activate ((IntPtr
)ModalWindows
.Peek ());
1425 pending
= XPending (DisplayHandle
);
1430 private IntPtr
GetMousewParam (int Delta
)
1434 if ((MouseState
& MouseButtons
.Left
) != 0) {
1435 result
|= (int)MsgButtons
.MK_LBUTTON
;
1438 if ((MouseState
& MouseButtons
.Middle
) != 0) {
1439 result
|= (int)MsgButtons
.MK_MBUTTON
;
1442 if ((MouseState
& MouseButtons
.Right
) != 0) {
1443 result
|= (int)MsgButtons
.MK_RBUTTON
;
1446 Keys mods
= ModifierKeys
;
1447 if ((mods
& Keys
.Control
) != 0) {
1448 result
|= (int)MsgButtons
.MK_CONTROL
;
1451 if ((mods
& Keys
.Shift
) != 0) {
1452 result
|= (int)MsgButtons
.MK_SHIFT
;
1455 result
|= Delta
<< 16;
1457 return (IntPtr
)result
;
1459 private IntPtr
XGetParent (IntPtr handle
)
1461 return gdk_x11_drawable_get_xid (gdk_window_get_parent (gdk_window_lookup (handle
)));
1464 private int HandleError (IntPtr display
, ref XErrorEvent error_event
)
1466 if (ErrorExceptions
) {
1467 throw new XException (error_event
.display
, error_event
.resourceid
, error_event
.serial
, error_event
.error_code
, error_event
.request_code
, error_event
.minor_code
);
1469 Console
.WriteLine ("X11 Error encountered: {0}{1}\n", XException
.GetMessage (error_event
.display
, error_event
.resourceid
, error_event
.serial
, error_event
.error_code
, error_event
.request_code
, error_event
.minor_code
), Environment
.StackTrace
);
1474 private void DestroyChildWindow (Control c
)
1481 controls
= c
.Controls
.GetAllControls ();
1483 for (i
= 0; i
< controls
.Length
; i
++) {
1484 if (controls
[i
].IsHandleCreated
) {
1485 hwnd
= Hwnd
.ObjectFromHandle (controls
[i
].Handle
);
1486 SendMessage (controls
[i
].Handle
, Msg
.WM_DESTROY
, IntPtr
.Zero
, IntPtr
.Zero
);
1489 DestroyChildWindow (controls
[i
]);
1494 #endregion // Private Methods
1497 private void MouseHover (object sender
, EventArgs e
)
1499 if ((HoverState
.X
== MousePosition
.X
) && (HoverState
.Y
== MousePosition
.Y
)) {
1502 HoverState
.Timer
.Enabled
= false;
1504 if (HoverState
.Window
!= IntPtr
.Zero
) {
1505 xevent
= new XEvent ();
1507 xevent
.type
= XEventName
.ClientMessage
;
1508 xevent
.ClientMessageEvent
.display
= DisplayHandle
;
1509 xevent
.ClientMessageEvent
.window
= (IntPtr
)HoverState
.Window
;
1510 xevent
.ClientMessageEvent
.message_type
= (IntPtr
)HoverState
.Atom
;
1511 xevent
.ClientMessageEvent
.format
= 32;
1512 xevent
.ClientMessageEvent
.ptr1
= (IntPtr
) (HoverState
.Y
<< 16 | HoverState
.X
);
1514 MessageQueue
.EnqueueLocked (xevent
);
1521 private void CaretCallback (object sender
, EventArgs e
)
1526 Caret
.On
= !Caret
.On
;
1528 XDrawLine (DisplayHandle
, Caret
.Hwnd
, Caret
.gc
, Caret
.X
, Caret
.Y
, Caret
.X
, Caret
.Y
+ Caret
.Height
);
1530 #endregion // Callbacks
1532 #region Public Properties
1534 internal override int Caption
{
1540 internal override Size CursorSize
{
1544 gdk_display_get_maximal_cursor_size (GdkDisplayHandle
, out x
, out y
);
1546 return new Size ((int)x
, (int)y
);
1550 internal override bool DragFullWindows
{
1556 internal override Size DragSize
{
1558 return new Size (4, 4);
1562 internal override Size FrameBorderSize
{
1564 throw new NotImplementedException ();
1568 internal override Size IconSize
{
1574 if (XGetIconSizes (DisplayHandle
, RootWindow
, out list
, out count
) != 0) {
1578 current
= (long)list
;
1581 size
= new XIconSize ();
1583 for (int i
= 0; i
< count
; i
++) {
1584 size
= (XIconSize
)Marshal
.PtrToStructure ((IntPtr
)current
, size
.GetType ());
1585 current
+= Marshal
.SizeOf (size
);
1587 // Look for our preferred size
1588 if (size
.min_width
== 32) {
1590 return new Size (32, 32);
1593 if (size
.max_width
== 32) {
1595 return new Size (32, 32);
1598 if (size
.min_width
< 32 && size
.max_width
> 32) {
1601 // check if we can fit one
1603 while (x
< size
.max_width
) {
1604 x
+= size
.width_inc
;
1607 return new Size (32, 32);
1612 if (largest
< size
.max_width
) {
1613 largest
= size
.max_width
;
1617 // We didn't find a match or we wouldn't be here
1618 return new Size (largest
, largest
);
1621 return new Size (32, 32);
1626 internal override int KeyboardSpeed
{
1629 // A lot harder: need to do:
1630 // XkbQueryExtension(0x08051008, 0xbfffdf4c, 0xbfffdf50, 0xbfffdf54, 0xbfffdf58) = 1
1631 // XkbAllocKeyboard(0x08051008, 0xbfffdf4c, 0xbfffdf50, 0xbfffdf54, 0xbfffdf58) = 0x080517a8
1632 // XkbGetControls(0x08051008, 1, 0x080517a8, 0xbfffdf54, 0xbfffdf58) = 0
1634 // And from that we can tell the repetition rate
1636 // Notice, the values must map to:
1637 // [0, 31] which maps to 2.5 to 30 repetitions per second.
1643 internal override int KeyboardDelay
{
1646 // Return values must range from 0 to 4, 0 meaning 250ms,
1647 // and 4 meaning 1000 ms.
1649 return 1; // ie, 500 ms
1653 internal override Size MaxWindowTrackSize
{
1655 return new Size (WorkingArea
.Width
, WorkingArea
.Height
);
1659 internal override Size MinimizedWindowSize
{
1661 return new Size (1, 1);
1665 internal override Size MinimizedWindowSpacingSize
{
1667 return new Size (1, 1);
1671 internal override Size MinimumWindowSize
{
1673 return new Size (1, 1);
1677 internal override Size MinWindowTrackSize
{
1679 return new Size (1, 1);
1683 internal override Keys ModifierKeys
{
1685 return Keyboard
.ModifierKeys
;
1689 internal override Size SmallIconSize
{
1695 if (XGetIconSizes (DisplayHandle
, RootWindow
, out list
, out count
) != 0) {
1699 current
= (long)list
;
1702 size
= new XIconSize ();
1704 for (int i
= 0; i
< count
; i
++) {
1705 size
= (XIconSize
)Marshal
.PtrToStructure ((IntPtr
)current
, size
.GetType ());
1706 current
+= Marshal
.SizeOf (size
);
1708 // Look for our preferred size
1709 if (size
.min_width
== 16) {
1711 return new Size (16, 16);
1714 if (size
.max_width
== 16) {
1716 return new Size (16, 16);
1719 if (size
.min_width
< 16 && size
.max_width
> 16) {
1722 // check if we can fit one
1724 while (x
< size
.max_width
) {
1725 x
+= size
.width_inc
;
1728 return new Size (16, 16);
1733 if (smallest
== 0 || smallest
> size
.min_width
) {
1734 smallest
= size
.min_width
;
1738 // We didn't find a match or we wouldn't be here
1739 return new Size (smallest
, smallest
);
1742 return new Size (16, 16);
1747 internal override int MouseButtonCount
{
1753 internal override bool MouseButtonsSwapped
{
1755 return false; // FIXME - how to detect?
1759 internal override bool MouseWheelPresent
{
1761 return true; // FIXME - how to detect?
1765 internal override Rectangle VirtualScreen
{
1771 internal override Rectangle WorkingArea
{
1777 IntPtr prop
= IntPtr
.Zero
;
1781 XGetWindowProperty (DisplayHandle
, RootWindow
, NetAtoms
[(int)NA
._NET_DESKTOP_GEOMETRY
], 0, 256, false, Atom
.XA_CARDINAL
, out actual_atom
, out actual_format
, out nitems
, out bytes_after
, ref prop
);
1782 if ((nitems
== 2) && (prop
!= IntPtr
.Zero
)) {
1783 width
= Marshal
.ReadInt32 (prop
, 0);
1784 height
= Marshal
.ReadInt32 (prop
, 4);
1787 return new Rectangle (0, 0, width
, height
);
1789 XWindowAttributes attributes
=new XWindowAttributes ();
1792 XGetWindowAttributes (DisplayHandle
, XRootWindow (DisplayHandle
, ScreenNo
), ref attributes
);
1795 return new Rectangle (0, 0, attributes
.width
, attributes
.height
);
1799 #endregion // Public properties
1801 #region Public Static Methods
1802 internal override IntPtr
InitializeDriver ()
1805 if (GdkDisplayHandle
== IntPtr
.Zero
) {
1806 SetDisplay (gdk_x11_display_get_xdisplay (gdk_display_get_default ()));
1812 internal override void ShutdownDriver (IntPtr token
)
1815 if (GdkDisplayHandle
!= IntPtr
.Zero
) {
1816 gdk_display_close (GdkDisplayHandle
);
1817 DisplayHandle
= IntPtr
.Zero
;
1818 GdkDisplayHandle
= IntPtr
.Zero
;
1823 internal override void EnableThemes ()
1825 ThemesEnabled
= true;
1829 internal override void Activate (IntPtr handle
)
1833 hwnd
= Hwnd
.ObjectFromHandle (handle
);
1835 if (hwnd
!= null) lock (XlibLock
) {
1836 SendNetWMMessage (hwnd
.whole_window
, (IntPtr
)NetAtoms
[(int)NA
._NET_ACTIVE_WINDOW
], IntPtr
.Zero
, IntPtr
.Zero
, IntPtr
.Zero
);
1837 //XRaiseWindow(DisplayHandle, handle);
1842 internal override void AudibleAlert ()
1844 gdk_display_beep (gdk_x11_lookup_xdisplay (DisplayHandle
));
1849 internal override void CaretVisible (IntPtr handle
, bool visible
)
1851 // Visible is cumulative; two hides require two shows before the caret is visible again
1852 if (Caret
.Hwnd
== handle
) {
1854 if (Caret
.Visible
< 1) {
1857 if (Caret
.Visible
== 1) {
1859 Caret
.Timer
.Start ();
1864 if (Caret
.Visible
== 0) {
1865 Caret
.Timer
.Stop ();
1872 internal override bool CalculateWindowRect (IntPtr handle
, ref Rectangle ClientRect
, int Style
, int ExStyle
, Menu menu
, out Rectangle WindowRect
)
1874 FormBorderStyle border_style
;
1875 TitleStyle title_style
;
1877 int tool_caption_height
;
1879 DeriveStyles (handle
, Style
, ExStyle
, out border_style
, out title_style
,
1880 out caption_height
, out tool_caption_height
);
1882 WindowRect
= Hwnd
.GetWindowRectangle (border_style
, menu
, title_style
,
1883 caption_height
, tool_caption_height
,
1889 internal override void ClientToScreen (IntPtr handle
, ref int x
, ref int y
)
1896 hwnd
= Hwnd
.ObjectFromHandle (handle
);
1899 XTranslateCoordinates (DisplayHandle
, hwnd
.client_window
, RootWindow
, x
, y
, out dest_x_return
, out dest_y_return
, out child
);
1906 internal override int[] ClipboardAvailableFormats (IntPtr handle
)
1908 DataFormats
.Format f
;
1911 f
= DataFormats
.Format
.List
;
1913 if (XGetSelectionOwner (DisplayHandle
, NetAtoms
[(int)NA
.CLIPBOARD
]) == IntPtr
.Zero
) {
1917 Clipboard
.Formats
= new ArrayList ();
1920 XConvertSelection (DisplayHandle
, NetAtoms
[(int)NA
.CLIPBOARD
], f
.Id
, f
.Id
, FosterParent
, IntPtr
.Zero
);
1922 Clipboard
.Enumerating
= true;
1923 while (Clipboard
.Enumerating
) {
1924 UpdateMessageQueue ();
1929 result
= new int [Clipboard
.Formats
.Count
];
1931 for (int i
= 0; i
< Clipboard
.Formats
.Count
; i
++) {
1932 result
[i
] = (int)Clipboard
.Formats
[i
];
1935 Clipboard
.Formats
= null;
1939 internal override void ClipboardClose (IntPtr handle
)
1941 if (handle
!= ClipMagic
) {
1942 throw new ArgumentException ("handle is not a valid clipboard handle");
1947 internal override int ClipboardGetID (IntPtr handle
, string format
)
1949 if (handle
!= ClipMagic
) {
1950 throw new ArgumentException ("handle is not a valid clipboard handle");
1953 if (format
== "Text") return (int)Atom
.XA_STRING
;
1954 else if (format
== "Bitmap") return (int)Atom
.XA_BITMAP
;
1955 //else if (format == "MetaFilePict" ) return 3;
1956 //else if (format == "SymbolicLink" ) return 4;
1957 //else if (format == "DataInterchangeFormat" ) return 5;
1958 //else if (format == "Tiff" ) return 6;
1959 else if (format
== "OEMText") return XInternAtom (DisplayHandle
, "COMPOUND_TEXT", false);
1960 else if (format
== "DeviceIndependentBitmap") return (int)Atom
.XA_PIXMAP
;
1961 else if (format
== "Palette") return (int)Atom
.XA_COLORMAP
; // Useless
1962 //else if (format == "PenData" ) return 10;
1963 //else if (format == "RiffAudio" ) return 11;
1964 //else if (format == "WaveAudio" ) return 12;
1965 else if (format
== "UnicodeText") return XInternAtom (DisplayHandle
, "UTF8_STRING", false);
1966 //else if (format == "EnhancedMetafile" ) return 14;
1967 //else if (format == "FileDrop" ) return 15;
1968 //else if (format == "Locale" ) return 16;
1970 return XInternAtom (DisplayHandle
, format
, false);
1973 internal override IntPtr
ClipboardOpen ()
1978 internal override object ClipboardRetrieve (IntPtr handle
, int type
, XplatUI
.ClipboardToObject converter
)
1980 XConvertSelection (DisplayHandle
, NetAtoms
[(int)NA
.CLIPBOARD
], type
, type
, FosterParent
, IntPtr
.Zero
);
1982 Clipboard
.Retrieving
= true;
1983 while (Clipboard
.Retrieving
) {
1984 UpdateMessageQueue ();
1987 return Clipboard
.Item
;
1990 internal override void ClipboardStore (IntPtr handle
, object obj
, int type
, XplatUI
.ObjectToClipboard converter
)
1992 Clipboard
.Item
= obj
;
1993 Clipboard
.Type
= type
;
1994 Clipboard
.Converter
= converter
;
1997 XSetSelectionOwner (DisplayHandle
, NetAtoms
[(int)NA
.CLIPBOARD
], FosterParent
, IntPtr
.Zero
);
1999 // Clearing the selection
2000 XSetSelectionOwner (DisplayHandle
, NetAtoms
[(int)NA
.CLIPBOARD
], IntPtr
.Zero
, IntPtr
.Zero
);
2004 internal override void CreateCaret (IntPtr handle
, int width
, int height
)
2006 XGCValues gc_values
;
2009 hwnd
= Hwnd
.ObjectFromHandle (handle
);
2011 if (Caret
.Hwnd
!= IntPtr
.Zero
) {
2012 DestroyCaret (Caret
.Hwnd
);
2015 Caret
.Hwnd
= handle
;
2016 Caret
.Window
= hwnd
.client_window
;
2017 Caret
.Width
= width
;
2018 Caret
.Height
= height
;
2022 gc_values
= new XGCValues ();
2023 gc_values
.line_width
= width
;
2025 Caret
.gc
= XCreateGC (DisplayHandle
, Caret
.Window
, GCFunction
.GCLineWidth
, ref gc_values
);
2026 if (Caret
.gc
== IntPtr
.Zero
) {
2027 Caret
.Hwnd
= IntPtr
.Zero
;
2031 XSetFunction (DisplayHandle
, Caret
.gc
, GXFunction
.GXinvert
);
2034 internal override IntPtr
CreateWindow (CreateParams cp
)
2036 GdkWindowAttr gdk_window_attributes
;
2037 GdkWindowAttributesType attributes_mask
= 0;
2043 IntPtr GdkParentHandle
;
2044 IntPtr GdkWholeWindow
;
2045 IntPtr GdkClientWindow
;
2046 Rectangle ClientRect
;
2047 GdkWindowType gdk_window_type
;
2052 gdk_window_attributes
= new GdkWindowAttr ();
2059 if (Width
< 1) Width
= 1;
2060 if (Height
< 1) Height
= 1;
2062 gdk_window_type
= GdkWindowType
.GDK_WINDOW_CHILD
;
2064 if (cp
.Parent
!= IntPtr
.Zero
) {
2065 GdkParentHandle
= gdk_window_lookup (Hwnd
.ObjectFromHandle (cp
.Parent
).client_window
);
2067 if ((cp
.Style
& (int)WindowStyles
.WS_CHILD
) != 0) {
2068 // We need to use our foster parent window until this poor child gets it's parent assigned
2069 GdkParentHandle
= GdkFosterParent
;
2070 } else if ((cp
.Style
& (int)WindowStyles
.WS_POPUP
) != 0) {
2071 GdkParentHandle
= GdkRootWindow
;
2073 // Default position on screen, if window manager doesn't place us somewhere else
2076 GdkParentHandle
= GdkRootWindow
;
2080 // ValueMask = SetWindowValuemask.BitGravity | SetWindowValuemask.WinGravity;
2082 // Attributes.bit_gravity = Gravity.NorthWestGravity;
2083 // Attributes.win_gravity = Gravity.NorthWestGravity;
2085 // FIXME: does gdk need that ?
2086 // Save what's under the toolwindow
2087 if ((cp
.ExStyle
& (int)WindowStyles
.WS_EX_TOOLWINDOW
) != 0) {
2088 // Attributes.save_under = true;
2089 // ValueMask |= SetWindowValuemask.SaveUnder;
2092 // If we're a popup without caption we override the WM
2093 if ((cp
.Style
& ((int)WindowStyles
.WS_POPUP
)) != 0) {
2094 if ((cp
.Style
& (int)WindowStyles
.WS_CAPTION
) == 0) {
2095 gdk_window_attributes
.override_redirect
= true;
2096 attributes_mask
|= GdkWindowAttributesType
.GDK_WA_NOREDIR
;
2103 hwnd
.height
= Height
;
2104 hwnd
.parent
= Hwnd
.ObjectFromHandle (cp
.Parent
);
2106 if ((cp
.Style
& ((int)WindowStyles
.WS_DISABLED
)) != 0) {
2107 hwnd
.enabled
= false;
2110 ClientRect
= hwnd
.ClientRect
;
2111 GdkClientWindow
= IntPtr
.Zero
;
2113 gdk_window_attributes
.x
= X
;
2114 gdk_window_attributes
.y
= Y
;
2115 gdk_window_attributes
.width
= Width
;
2116 gdk_window_attributes
.height
= Height
;
2117 gdk_window_attributes
.window_type
= gdk_window_type
;
2119 attributes_mask
|= GdkWindowAttributesType
.GDK_WA_X
| GdkWindowAttributesType
.GDK_WA_Y
;
2121 gdk_window_attributes
.wclass
= GdkWindowClass
.GDK_INPUT_OUTPUT
;
2124 GdkWholeWindow
= gdk_window_new (GdkParentHandle
, ref gdk_window_attributes
, (int)attributes_mask
);
2126 if (GdkWholeWindow
!= IntPtr
.Zero
) {
2127 attributes_mask
&= ~GdkWindowAttributesType
.GDK_WA_NOREDIR
;
2129 if (GdkCustomVisual
!= IntPtr
.Zero
&& GdkCustomColormap
!= IntPtr
.Zero
) {
2130 attributes_mask
|= GdkWindowAttributesType
.GDK_WA_COLORMAP
| GdkWindowAttributesType
.GDK_WA_VISUAL
;
2131 gdk_window_attributes
.colormap
= GdkCustomColormap
;
2132 gdk_window_attributes
.visual
= GdkCustomVisual
;
2135 gdk_window_attributes
.x
= ClientRect
.X
;
2136 gdk_window_attributes
.y
= ClientRect
.Y
;
2137 gdk_window_attributes
.width
= ClientRect
.Width
;
2138 gdk_window_attributes
.height
= ClientRect
.Height
;
2140 GdkClientWindow
= gdk_window_new (GdkWholeWindow
, ref gdk_window_attributes
, (int)attributes_mask
);
2144 if ((GdkWholeWindow
== IntPtr
.Zero
) || (GdkClientWindow
== IntPtr
.Zero
)) {
2145 throw new Exception ("Could not create X11 Gdk windows");
2148 hwnd
.WholeWindow
= gdk_x11_drawable_get_xid (GdkWholeWindow
);
2149 hwnd
.ClientWindow
= gdk_x11_drawable_get_xid (GdkClientWindow
);
2152 Console
.WriteLine("Created window {0:X} / {1:X} parent {2:X}", ClientWindow
.ToInt32(), WholeWindow
.ToInt32(), hwnd
.parent
!= null ? hwnd
.parent
.Handle
.ToInt32() : 0);
2156 gdk_window_set_events (GdkWholeWindow
, (int)GdkSelectInputMask
);
2157 gdk_window_set_events (GdkClientWindow
, (int)GdkSelectInputMask
);
2159 if ((cp
.Style
& (int)WindowStyles
.WS_VISIBLE
) != 0) {
2160 gdk_window_show (GdkWholeWindow
);
2161 gdk_window_show (GdkClientWindow
);
2162 hwnd
.visible
= true;
2166 SetWMStyles (hwnd
, cp
);
2168 if ((cp
.Style
& (int)WindowStyles
.WS_MINIMIZE
) != 0) {
2169 SetWindowState (hwnd
.Handle
, FormWindowState
.Minimized
);
2170 } else if ((cp
.Style
& (int)WindowStyles
.WS_MAXIMIZE
) != 0) {
2171 SetWindowState (hwnd
.Handle
, FormWindowState
.Maximized
);
2174 // for now make all windows dnd enabled
2175 Dnd
.SetAllowDrop (hwnd
, true);
2177 // Set caption/window title
2178 Text (hwnd
.Handle
, cp
.Caption
);
2183 internal override IntPtr
CreateWindow (IntPtr Parent
, int X
, int Y
, int Width
, int Height
)
2185 CreateParams create_params
= new CreateParams ();
2187 create_params
.Caption
= "";
2188 create_params
.X
= X
;
2189 create_params
.Y
= Y
;
2190 create_params
.Width
= Width
;
2191 create_params
.Height
= Height
;
2193 create_params
.ClassName
= XplatUI
.DefaultClassName
;
2194 create_params
.ClassStyle
= 0;
2195 create_params
.ExStyle
= 0;
2196 create_params
.Parent
= IntPtr
.Zero
;
2197 create_params
.Param
= 0;
2199 return CreateWindow (create_params
);
2202 internal override IntPtr
DefineCursor (Bitmap bitmap
, Bitmap mask
, Color cursor_pixel
, Color mask_pixel
, int xHotSpot
, int yHotSpot
)
2205 Bitmap cursor_bitmap
;
2213 IntPtr cursor_pixmap
;
2220 Size cursor_size
= CursorSize
;
2221 width
= cursor_size
.Width
;
2222 height
= cursor_size
.Height
;
2224 // Win32 only allows creation cursors of a certain size
2225 if ((bitmap
.Width
!= width
) || (bitmap
.Width
!= height
)) {
2226 cursor_bitmap
= new Bitmap (bitmap
, new Size (width
, height
));
2227 cursor_mask
= new Bitmap (mask
, new Size (width
, height
));
2229 cursor_bitmap
= bitmap
;
2233 width
= cursor_bitmap
.Width
;
2234 height
= cursor_bitmap
.Height
;
2236 cursor_bits
= new Byte
[(width
/ 8) * height
];
2237 mask_bits
= new Byte
[(width
/ 8) * height
];
2239 for (int y
= 0; y
< height
; y
++) {
2240 for (int x
= 0; x
< width
; x
++) {
2241 c_pixel
= cursor_bitmap
.GetPixel (x
, y
);
2242 m_pixel
= cursor_mask
.GetPixel (x
, y
);
2244 and
= c_pixel
== cursor_pixel
;
2245 xor
= m_pixel
== mask_pixel
;
2249 // cursor_bits[y * width / 8 + x / 8] &= (byte)~((1 << (x % 8))); // The bit already is 0
2250 mask_bits
[y
* width
/ 8 + x
/ 8] |= (byte)(1 << (x
% 8));
2251 } else if (and
&& !xor
) {
2253 cursor_bits
[y
* width
/ 8 + x
/ 8] |= (byte)(1 << (x
% 8));
2254 mask_bits
[y
* width
/ 8 + x
/ 8] |= (byte)(1 << (x
% 8));
2256 } else if (and
&& !xor
) {
2258 } else if (and
&& xor
) {
2261 // X11 doesn't know the 'reverse screen' concept, so we'll treat them the same
2262 // we want both to be 0 so nothing to be done
2263 //cursor_bits[y * width / 8 + x / 8] &= (byte)~((1 << (x % 8)));
2264 //mask_bits[y * width / 8 + x / 8] |= (byte)(01 << (x % 8));
2270 cursor_pixmap
= XCreatePixmapFromBitmapData (DisplayHandle
, RootWindow
, cursor_bits
, width
, height
, (IntPtr
)1, (IntPtr
)0, 1);
2271 mask_pixmap
= XCreatePixmapFromBitmapData (DisplayHandle
, RootWindow
, mask_bits
, width
, height
, (IntPtr
)1, (IntPtr
)0, 1);
2275 fg
.pixel
= XWhitePixel (DisplayHandle
, ScreenNo
);
2276 fg
.red
= (ushort)65535;
2277 fg
.green
= (ushort)65535;
2278 fg
.blue
= (ushort)65535;
2280 bg
.pixel
= XBlackPixel (DisplayHandle
, ScreenNo
);
2282 cursor
= XCreatePixmapCursor (DisplayHandle
, cursor_pixmap
, mask_pixmap
, ref fg
, ref bg
, xHotSpot
, yHotSpot
);
2284 XFreePixmap (DisplayHandle
, cursor_pixmap
);
2285 XFreePixmap (DisplayHandle
, mask_pixmap
);
2290 internal override IntPtr
DefineStdCursor (StdCursor id
)
2292 CursorFontShape shape
;
2295 // FIXME - define missing shapes
2298 case StdCursor
.AppStarting
: {
2299 shape
= CursorFontShape
.XC_watch
;
2303 case StdCursor
.Arrow
: {
2307 case StdCursor
.Cross
: {
2308 shape
= CursorFontShape
.XC_crosshair
;
2312 case StdCursor
.Default
: {
2316 case StdCursor
.Hand
: {
2317 shape
= CursorFontShape
.XC_hand1
;
2321 case StdCursor
.Help
: {
2322 shape
= CursorFontShape
.XC_question_arrow
;
2326 case StdCursor
.HSplit
: {
2327 shape
= CursorFontShape
.XC_sb_v_double_arrow
;
2331 case StdCursor
.IBeam
: {
2332 shape
= CursorFontShape
.XC_xterm
;
2336 case StdCursor
.No
: {
2337 shape
= CursorFontShape
.XC_circle
;
2341 case StdCursor
.NoMove2D
: {
2342 shape
= CursorFontShape
.XC_fleur
;
2346 case StdCursor
.NoMoveHoriz
: {
2347 shape
= CursorFontShape
.XC_fleur
;
2351 case StdCursor
.NoMoveVert
: {
2352 shape
= CursorFontShape
.XC_fleur
;
2356 case StdCursor
.PanEast
: {
2357 shape
= CursorFontShape
.XC_fleur
;
2361 case StdCursor
.PanNE
: {
2362 shape
= CursorFontShape
.XC_fleur
;
2366 case StdCursor
.PanNorth
: {
2367 shape
= CursorFontShape
.XC_fleur
;
2371 case StdCursor
.PanNW
: {
2372 shape
= CursorFontShape
.XC_fleur
;
2376 case StdCursor
.PanSE
: {
2377 shape
= CursorFontShape
.XC_fleur
;
2381 case StdCursor
.PanSouth
: {
2382 shape
= CursorFontShape
.XC_fleur
;
2386 case StdCursor
.PanSW
: {
2387 shape
= CursorFontShape
.XC_fleur
;
2391 case StdCursor
.PanWest
: {
2392 shape
= CursorFontShape
.XC_sizing
;
2396 case StdCursor
.SizeAll
: {
2397 shape
= CursorFontShape
.XC_fleur
;
2401 case StdCursor
.SizeNESW
: {
2402 shape
= CursorFontShape
.XC_top_right_corner
;
2406 case StdCursor
.SizeNS
: {
2407 shape
= CursorFontShape
.XC_sb_v_double_arrow
;
2411 case StdCursor
.SizeNWSE
: {
2412 shape
= CursorFontShape
.XC_top_left_corner
;
2416 case StdCursor
.SizeWE
: {
2417 shape
= CursorFontShape
.XC_sb_h_double_arrow
;
2421 case StdCursor
.UpArrow
: {
2422 shape
= CursorFontShape
.XC_center_ptr
;
2426 case StdCursor
.VSplit
: {
2427 shape
= CursorFontShape
.XC_sb_h_double_arrow
;
2431 case StdCursor
.WaitCursor
: {
2432 shape
= CursorFontShape
.XC_watch
;
2442 cursor
= XCreateFontCursor (DisplayHandle
, shape
);
2447 internal override IntPtr
DefWndProc (ref Message msg
)
2452 internal override void DestroyCaret (IntPtr handle
)
2454 if (Caret
.Hwnd
== handle
) {
2455 if (Caret
.Visible
== 1) {
2456 Caret
.Timer
.Stop ();
2459 if (Caret
.gc
!= IntPtr
.Zero
) {
2460 XFreeGC (DisplayHandle
, Caret
.gc
);
2461 Caret
.gc
= IntPtr
.Zero
;
2463 Caret
.Hwnd
= IntPtr
.Zero
;
2469 internal override void DestroyCursor (IntPtr cursor
)
2472 XFreeCursor (DisplayHandle
, cursor
);
2476 internal override void DestroyWindow (IntPtr handle
)
2480 hwnd
= Hwnd
.ObjectFromHandle (handle
);
2484 Console
.WriteLine("window {0:X} already destroyed", handle
.ToInt32());
2490 Console
.WriteLine("Destroying window {0:X}", handle
.ToInt32());
2493 // Make sure if the caret is in the window, that we destroy the caret, too
2494 if (Caret
.Hwnd
== hwnd
.client_window
) {
2495 DestroyCaret (handle
);
2498 // Mark our children as gone as well
2499 DestroyChildWindow (Control
.ControlNativeWindow
.ControlFromHandle (handle
));
2501 // Send destroy message
2502 SendMessage (handle
, Msg
.WM_DESTROY
, IntPtr
.Zero
, IntPtr
.Zero
);
2505 if (hwnd
.client_window
!= IntPtr
.Zero
) {
2506 gdk_window_destroy (gdk_window_lookup (hwnd
.client_window
));
2509 if ((hwnd
.whole_window
!= IntPtr
.Zero
) && (hwnd
.whole_window
!= hwnd
.client_window
)) {
2510 gdk_window_destroy (gdk_window_lookup (hwnd
.whole_window
));
2516 internal override IntPtr
DispatchMessage (ref MSG msg
)
2518 return NativeWindow
.WndProc (msg
.hwnd
, msg
.message
, msg
.wParam
, msg
.lParam
);
2521 internal override void DrawReversibleRectangle (IntPtr handle
, Rectangle rect
, int line_width
)
2524 XGCValues gc_values
;
2527 hwnd
= Hwnd
.ObjectFromHandle (handle
);
2529 gc_values
= new XGCValues ();
2531 gc_values
.subwindow_mode
= GCSubwindowMode
.IncludeInferiors
;
2532 gc_values
.line_width
= line_width
;
2533 gc_values
.foreground
= XBlackPixel (DisplayHandle
, ScreenNo
);
2535 // This logic will give us true rubber bands: (libsx, SANE_XOR)
2536 //mask = foreground ^ background;
2537 //XSetForeground(DisplayHandle, gc, 0xffffffff);
2538 //XSetBackground(DisplayHandle, gc, background);
2539 //XSetFunction(DisplayHandle, gc, GXxor);
2540 //XSetPlaneMask(DisplayHandle, gc, mask);
2543 gc
= XCreateGC (DisplayHandle
, hwnd
.client_window
, GCFunction
.GCSubwindowMode
| GCFunction
.GCLineWidth
| GCFunction
.GCForeground
, ref gc_values
);
2548 control
= Control
.FromHandle (handle
);
2550 XColor xcolor
= new XColor ();
2552 xcolor
.red
= (ushort)(control
.ForeColor
.R
* 257);
2553 xcolor
.green
= (ushort)(control
.ForeColor
.G
* 257);
2554 xcolor
.blue
= (ushort)(control
.ForeColor
.B
* 257);
2555 XAllocColor (DisplayHandle
, DefaultColormap
, ref xcolor
);
2556 foreground
= (uint)xcolor
.pixel
.ToInt32 ();
2558 xcolor
.red
= (ushort)(control
.BackColor
.R
* 257);
2559 xcolor
.green
= (ushort)(control
.BackColor
.G
* 257);
2560 xcolor
.blue
= (ushort)(control
.BackColor
.B
* 257);
2561 XAllocColor (DisplayHandle
, DefaultColormap
, ref xcolor
);
2562 background
= (uint)xcolor
.pixel
.ToInt32 ();
2564 uint mask
= foreground ^ background
;
2566 XSetForeground (DisplayHandle
, gc
, 0xffffffff);
2567 XSetBackground (DisplayHandle
, gc
, background
);
2568 XSetFunction (DisplayHandle
, gc
, GXFunction
.GXxor
);
2569 XSetPlaneMask (DisplayHandle
, gc
, mask
);
2571 if ((rect
.Width
> 0) && (rect
.Height
> 0)) {
2572 XDrawRectangle (DisplayHandle
, hwnd
.client_window
, gc
, rect
.Left
, rect
.Top
, rect
.Width
, rect
.Height
);
2574 if (rect
.Width
> 0) {
2575 XDrawLine (DisplayHandle
, hwnd
.client_window
, gc
, rect
.X
, rect
.Y
, rect
.Right
, rect
.Y
);
2577 XDrawLine (DisplayHandle
, hwnd
.client_window
, gc
, rect
.X
, rect
.Y
, rect
.X
, rect
.Bottom
);
2580 XFreeGC (DisplayHandle
, gc
);
2583 internal override void DoEvents ()
2585 MSG msg
= new MSG ();
2587 if (OverrideCursorHandle
!= IntPtr
.Zero
) {
2588 OverrideCursorHandle
= IntPtr
.Zero
;
2591 while (PeekMessage (ref msg
, IntPtr
.Zero
, 0, 0, (uint)PeekMessageFlags
.PM_REMOVE
)) {
2592 TranslateMessage (ref msg
);
2593 DispatchMessage (ref msg
);
2597 internal override void EnableWindow (IntPtr handle
, bool Enable
)
2601 hwnd
= Hwnd
.ObjectFromHandle (handle
);
2603 hwnd
.Enabled
= Enable
;
2607 internal override void EndLoop (Thread thread
)
2609 // This is where we one day will shut down the loop for the thread
2613 internal override IntPtr
GetActive ()
2619 IntPtr prop
= IntPtr
.Zero
;
2620 IntPtr active
= IntPtr
.Zero
;
2622 XGetWindowProperty (DisplayHandle
, RootWindow
, NetAtoms
[(int)NA
._NET_ACTIVE_WINDOW
], 0, 1, false, Atom
.XA_WINDOW
, out actual_atom
, out actual_format
, out nitems
, out bytes_after
, ref prop
);
2623 if ((nitems
> 0) && (prop
!= IntPtr
.Zero
)) {
2624 active
= (IntPtr
)Marshal
.ReadInt32 (prop
);
2628 if (active
!= IntPtr
.Zero
) {
2631 hwnd
= Hwnd
.GetObjectFromWindow (active
);
2633 active
= hwnd
.Handle
;
2635 active
= IntPtr
.Zero
;
2641 internal override void GetCursorInfo (IntPtr cursor
, out int width
, out int height
, out int hotspot_x
, out int hotspot_y
)
2643 throw new NotImplementedException ();
2646 internal override void GetDisplaySize (out Size size
)
2648 XWindowAttributes attributes
=new XWindowAttributes ();
2651 // FIXME - use _NET_WM messages instead?
2652 XGetWindowAttributes (DisplayHandle
, XRootWindow (DisplayHandle
, ScreenNo
), ref attributes
);
2655 size
= new Size (attributes
.width
, attributes
.height
);
2658 internal override SizeF
GetAutoScaleSize (Font font
)
2662 string magic_string
= "The quick brown fox jumped over the lazy dog.";
2663 double magic_number
= 44.549996948242189;
2665 g
= Graphics
.FromHwnd (FosterParent
);
2667 width
= (float) (g
.MeasureString (magic_string
, font
).Width
/ magic_number
);
2668 return new SizeF (width
, font
.Height
);
2671 internal override IntPtr
GetParent (IntPtr handle
)
2675 hwnd
= Hwnd
.ObjectFromHandle (handle
);
2676 if (hwnd
!= null && hwnd
.parent
!= null) {
2677 return hwnd
.parent
.Handle
;
2682 internal override void GetCursorPos (IntPtr handle
, out int x
, out int y
)
2693 if (handle
!= IntPtr
.Zero
) {
2694 use_handle
= Hwnd
.ObjectFromHandle (handle
).client_window
;
2696 use_handle
= RootWindow
;
2700 XQueryPointer (DisplayHandle
, use_handle
, out root
, out child
, out root_x
, out root_y
, out win_x
, out win_y
, out keys_buttons
);
2703 if (handle
!= IntPtr
.Zero
) {
2712 internal override bool GetFontMetrics (Graphics g
, Font font
, out int ascent
, out int descent
)
2714 return GetFontMetrics (g
.GetHdc (), font
.ToHfont (), out ascent
, out descent
);
2717 internal override Point
GetMenuOrigin (IntPtr handle
)
2721 hwnd
= Hwnd
.ObjectFromHandle (handle
);
2724 return hwnd
.MenuOrigin
;
2729 internal override bool GetMessage (ref MSG msg
, IntPtr handle
, int wFilterMin
, int wFilterMax
)
2737 if (MessageQueue
.Count
> 0) {
2738 xevent
= (XEvent
) MessageQueue
.Dequeue ();
2740 UpdateMessageQueue ();
2742 if (MessageQueue
.Count
> 0) {
2743 xevent
= (XEvent
) MessageQueue
.Dequeue ();
2745 if (!PostQuitState
) {
2746 msg
.hwnd
= IntPtr
.Zero
;
2747 msg
.message
= Msg
.WM_ENTERIDLE
;
2751 // We reset ourselves so GetMessage can be called again
2752 PostQuitState
= false;
2758 // FIXME - handle filtering
2760 hwnd
= Hwnd
.GetObjectFromWindow (xevent
.AnyEvent
.window
);
2762 // Handle messages for windows that are already or are about to be destroyed
2765 Console
.WriteLine("GetMessage(): Got message {0} for non-existent or already destroyed window {1:X}", xevent
.type
, xevent
.AnyEvent
.window
.ToInt32());
2767 goto ProcessNextMessage
;
2770 if (hwnd
.client_window
== xevent
.AnyEvent
.window
) {
2772 //Console.WriteLine("Client message, sending to window {0:X}", msg.hwnd.ToInt32());
2775 //Console.WriteLine("Non-Client message, sending to window {0:X}", msg.hwnd.ToInt32());
2778 msg
.hwnd
= hwnd
.Handle
;
2781 // If you add a new event to this switch make sure to add it in
2782 // UpdateMessage also unless it is not coming through the X event system.
2784 switch (xevent
.type
) {
2785 case XEventName
.KeyPress
: {
2786 Keyboard
.KeyEvent (FocusWindow
, xevent
, ref msg
);
2790 case XEventName
.KeyRelease
: {
2791 Keyboard
.KeyEvent (FocusWindow
, xevent
, ref msg
);
2795 case XEventName
.ButtonPress
: {
2796 switch (xevent
.ButtonEvent
.button
) {
2798 MouseState
|= MouseButtons
.Left
;
2800 msg
.message
= Msg
.WM_LBUTTONDOWN
;
2802 msg
.message
= Msg
.WM_NCLBUTTONDOWN
;
2803 WholeToScreen (msg
.hwnd
, ref xevent
.ButtonEvent
.x
, ref xevent
.ButtonEvent
.y
);
2805 // TODO: For WM_NCLBUTTONDOWN wParam specifies a hit-test value not the virtual keys down
2806 msg
.wParam
= GetMousewParam (0);
2811 MouseState
|= MouseButtons
.Middle
;
2813 msg
.message
= Msg
.WM_MBUTTONDOWN
;
2815 msg
.message
= Msg
.WM_NCMBUTTONDOWN
;
2816 WholeToScreen (msg
.hwnd
, ref xevent
.ButtonEvent
.x
, ref xevent
.ButtonEvent
.y
);
2818 msg
.wParam
= GetMousewParam (0);
2823 MouseState
|= MouseButtons
.Right
;
2825 msg
.message
= Msg
.WM_RBUTTONDOWN
;
2827 msg
.message
= Msg
.WM_NCRBUTTONDOWN
;
2828 WholeToScreen (msg
.hwnd
, ref xevent
.ButtonEvent
.x
, ref xevent
.ButtonEvent
.y
);
2830 msg
.wParam
= GetMousewParam (0);
2835 msg
.message
= Msg
.WM_MOUSEWHEEL
;
2836 msg
.wParam
= GetMousewParam (120);
2841 msg
.message
= Msg
.WM_MOUSEWHEEL
;
2842 msg
.wParam
= GetMousewParam (-120);
2848 msg
.lParam
= (IntPtr
) (xevent
.ButtonEvent
.y
<< 16 | xevent
.ButtonEvent
.x
);
2849 MousePosition
.X
= xevent
.ButtonEvent
.x
;
2850 MousePosition
.Y
= xevent
.ButtonEvent
.y
;
2852 if (!hwnd
.Enabled
) {
2855 msg
.hwnd
= hwnd
.EnabledHwnd
;
2856 XTranslateCoordinates (DisplayHandle
, xevent
.AnyEvent
.window
, Hwnd
.ObjectFromHandle (msg
.hwnd
).ClientWindow
, xevent
.ButtonEvent
.x
, xevent
.ButtonEvent
.y
, out xevent
.ButtonEvent
.x
, out xevent
.ButtonEvent
.y
, out dummy
);
2857 msg
.lParam
= (IntPtr
)(MousePosition
.Y
<< 16 | MousePosition
.X
);
2860 if (Grab
.Hwnd
!= IntPtr
.Zero
) {
2861 msg
.hwnd
= Grab
.Hwnd
;
2864 if (!ClickPending
.Pending
) {
2865 ClickPending
.Pending
= true;
2866 ClickPending
.Hwnd
= msg
.hwnd
;
2867 ClickPending
.Message
= msg
.message
;
2868 ClickPending
.wParam
= msg
.wParam
;
2869 ClickPending
.lParam
= msg
.lParam
;
2870 ClickPending
.Time
= (long)xevent
.ButtonEvent
.time
;
2872 if ((((long)xevent
.ButtonEvent
.time
- ClickPending
.Time
) < DoubleClickInterval
) && (msg
.wParam
== ClickPending
.wParam
) && (msg
.lParam
== ClickPending
.lParam
) && (msg
.message
== ClickPending
.Message
)) {
2873 // Looks like a genuine double click, clicked twice on the same spot with the same keys
2874 switch (xevent
.ButtonEvent
.button
) {
2876 msg
.message
= client
? Msg
.WM_LBUTTONDBLCLK
: Msg
.WM_NCLBUTTONDBLCLK
;
2881 msg
.message
= client
? Msg
.WM_MBUTTONDBLCLK
: Msg
.WM_NCMBUTTONDBLCLK
;
2886 msg
.message
= client
? Msg
.WM_RBUTTONDBLCLK
: Msg
.WM_NCRBUTTONDBLCLK
;
2891 ClickPending
.Pending
= false;
2897 case XEventName
.ButtonRelease
: {
2898 Dnd
.HandleButtonRelease (ref xevent
);
2899 switch (xevent
.ButtonEvent
.button
) {
2902 msg
.message
= Msg
.WM_LBUTTONUP
;
2904 msg
.message
= Msg
.WM_NCLBUTTONUP
;
2905 WholeToScreen (msg
.hwnd
, ref xevent
.ButtonEvent
.x
, ref xevent
.ButtonEvent
.y
);
2907 msg
.wParam
= GetMousewParam (0);
2908 MouseState
&= ~MouseButtons
.Left
;
2914 msg
.message
= Msg
.WM_MBUTTONUP
;
2916 msg
.message
= Msg
.WM_NCMBUTTONUP
;
2917 WholeToScreen (msg
.hwnd
, ref xevent
.ButtonEvent
.x
, ref xevent
.ButtonEvent
.y
);
2919 msg
.wParam
= GetMousewParam (0);
2920 MouseState
&= ~MouseButtons
.Middle
;
2926 msg
.message
= Msg
.WM_RBUTTONUP
;
2928 msg
.message
= Msg
.WM_NCRBUTTONUP
;
2929 WholeToScreen (msg
.hwnd
, ref xevent
.ButtonEvent
.x
, ref xevent
.ButtonEvent
.y
);
2931 msg
.wParam
= GetMousewParam (0);
2932 MouseState
&= ~MouseButtons
.Right
;
2937 goto ProcessNextMessage
;
2941 goto ProcessNextMessage
;
2945 if (!hwnd
.Enabled
) {
2948 msg
.hwnd
= hwnd
.EnabledHwnd
;
2949 XTranslateCoordinates (DisplayHandle
, xevent
.AnyEvent
.window
, Hwnd
.ObjectFromHandle (msg
.hwnd
).ClientWindow
, xevent
.ButtonEvent
.x
, xevent
.ButtonEvent
.y
, out xevent
.ButtonEvent
.x
, out xevent
.ButtonEvent
.y
, out dummy
);
2950 msg
.lParam
= (IntPtr
)(MousePosition
.Y
<< 16 | MousePosition
.X
);
2953 if (Grab
.Hwnd
!= IntPtr
.Zero
) {
2954 msg
.hwnd
= Grab
.Hwnd
;
2957 msg
.lParam
= (IntPtr
) (xevent
.ButtonEvent
.y
<< 16 | xevent
.ButtonEvent
.x
);
2958 MousePosition
.X
= xevent
.ButtonEvent
.x
;
2959 MousePosition
.Y
= xevent
.ButtonEvent
.y
;
2963 case XEventName
.MotionNotify
: {
2965 #if DriverDebugExtra
2966 Console
.WriteLine("GetMessage(): Window {0:X} MotionNotify x={1} y={2}", client
? hwnd
.client_window
.ToInt32() : hwnd
.whole_window
.ToInt32(), xevent
.MotionEvent
.x
, xevent
.MotionEvent
.y
);
2969 if (Dnd
.HandleMotionNotify (ref xevent
))
2970 goto ProcessNextMessage
;
2971 if (Grab
.Hwnd
!= IntPtr
.Zero
) {
2972 msg
.hwnd
= Grab
.Hwnd
;
2974 NativeWindow
.WndProc (msg
.hwnd
, Msg
.WM_SETCURSOR
, msg
.hwnd
, (IntPtr
)HitTest
.HTCLIENT
);
2977 msg
.message
= Msg
.WM_MOUSEMOVE
;
2978 msg
.wParam
= GetMousewParam (0);
2979 msg
.lParam
= (IntPtr
) (xevent
.MotionEvent
.y
<< 16 | xevent
.MotionEvent
.x
& 0xFFFF);
2981 if (!hwnd
.Enabled
) {
2984 msg
.hwnd
= hwnd
.EnabledHwnd
;
2985 XTranslateCoordinates (DisplayHandle
, xevent
.AnyEvent
.window
, Hwnd
.ObjectFromHandle (msg
.hwnd
).ClientWindow
, xevent
.MotionEvent
.x
, xevent
.MotionEvent
.y
, out xevent
.MotionEvent
.x
, out xevent
.MotionEvent
.y
, out dummy
);
2986 msg
.lParam
= (IntPtr
)(MousePosition
.Y
<< 16 | MousePosition
.X
);
2989 HoverState
.X
= MousePosition
.X
= xevent
.MotionEvent
.x
;
2990 HoverState
.Y
= MousePosition
.Y
= xevent
.MotionEvent
.y
;
2994 #if DriverDebugExtra
2995 Console
.WriteLine("GetMessage(): non-client area {0:X} MotionNotify x={1} y={2}", client
? hwnd
.client_window
.ToInt32() : hwnd
.whole_window
.ToInt32(), xevent
.MotionEvent
.x
, xevent
.MotionEvent
.y
);
2997 msg
.message
= Msg
.WM_NCMOUSEMOVE
;
2998 msg
.lParam
= (IntPtr
) (xevent
.MotionEvent
.y
<< 16 | xevent
.MotionEvent
.x
& 0xFFFF);
3000 if (!hwnd
.Enabled
) {
3003 msg
.hwnd
= hwnd
.EnabledHwnd
;
3004 XTranslateCoordinates (DisplayHandle
, xevent
.AnyEvent
.window
, Hwnd
.ObjectFromHandle (msg
.hwnd
).ClientWindow
, xevent
.MotionEvent
.x
, xevent
.MotionEvent
.y
, out xevent
.MotionEvent
.x
, out xevent
.MotionEvent
.y
, out dummy
);
3005 msg
.lParam
= (IntPtr
)(MousePosition
.Y
<< 16 | MousePosition
.X
);
3009 // Not sure we need this...
3011 ht
= NativeWindow
.WndProc(hwnd
.client_window
, Msg
.WM_NCHITTEST
, IntPtr
.Zero
, msg
.lParam
);
3014 MousePosition
.X
= xevent
.MotionEvent
.x
;
3015 MousePosition
.Y
= xevent
.MotionEvent
.y
;
3021 case XEventName
.EnterNotify
: {
3022 if (!hwnd
.Enabled
) {
3023 goto ProcessNextMessage
;
3025 if (xevent
.CrossingEvent
.mode
!= NotifyMode
.NotifyNormal
) {
3026 goto ProcessNextMessage
;
3028 msg
.message
= Msg
.WM_MOUSE_ENTER
;
3029 HoverState
.Timer
.Enabled
= true;
3030 HoverState
.Window
= xevent
.CrossingEvent
.window
;
3034 case XEventName
.LeaveNotify
: {
3035 if (!hwnd
.Enabled
) {
3036 goto ProcessNextMessage
;
3038 if (xevent
.CrossingEvent
.mode
!= NotifyMode
.NotifyNormal
) {
3039 goto ProcessNextMessage
;
3041 msg
.message
= Msg
.WM_MOUSELEAVE
;
3042 HoverState
.Timer
.Enabled
= false;
3043 HoverState
.Window
= IntPtr
.Zero
;
3048 case XEventName
.CreateNotify
: {
3049 if (client
&& (xevent
.ConfigureEvent
.xevent
== xevent
.ConfigureEvent
.window
)) {
3050 msg
.message
= WM_CREATE
;
3051 // Set up CreateStruct
3053 goto ProcessNextMessage
;
3060 case XEventName
.ReparentNotify
: {
3061 if (hwnd
.parent
== null) { // Toplevel
3062 if (xevent
.ReparentEvent
.parent
!= IntPtr
.Zero
) {
3063 // We need to adjust x/y
3066 hwnd
.Reparented
= true;
3068 gdk_window_get_geometry (gdk_window_lookup (hwnd
.whole_window
), out hwnd
.x
, out hwnd
.y
, out dummy_int
, out dummy_int
, out dummy_int
);
3069 msg
.message
= Msg
.WM_WINDOWPOSCHANGED
;
3070 if (hwnd
.opacity
!= 0xffffffff) {
3073 opacity
= hwnd
.opacity
;
3074 XChangeProperty (DisplayHandle
, XGetParent (hwnd
.whole_window
), NetAtoms
[(int)NA
._NET_WM_WINDOW_OPACITY
], Atom
.XA_CARDINAL
, 32, PropertyMode
.Replace
, ref opacity
, 1);
3077 hwnd
.Reparented
= false;
3078 goto ProcessNextMessage
;
3084 case XEventName
.ConfigureNotify
: {
3085 if (!client
&& (xevent
.ConfigureEvent
.xevent
== xevent
.ConfigureEvent
.window
)) { // Ignore events for children (SubstructureNotify) and client areas
3086 XplatUIWin32
.NCCALCSIZE_PARAMS ncp
;
3090 #if DriverDebugExtra
3091 Console
.WriteLine("GetMessage(): Window {0:X} ConfigureNotify x={1} y={2} width={3} height={4}", hwnd
.client_window
.ToInt32(), xevent
.ConfigureEvent
.x
, xevent
.ConfigureEvent
.y
, xevent
.ConfigureEvent
.width
, xevent
.ConfigureEvent
.height
);
3093 msg
.message
= Msg
.WM_WINDOWPOSCHANGED
;
3094 hwnd
.configure_pending
= false;
3096 // We need to adjust our client window to track the resize of whole_window
3097 rect
= hwnd
.DefaultClientRect
;
3099 ncp
= new XplatUIWin32
.NCCALCSIZE_PARAMS ();
3100 ptr
= Marshal
.AllocHGlobal (Marshal
.SizeOf (ncp
));
3102 ncp
.rgrc1
.left
= rect
.Left
;
3103 ncp
.rgrc1
.top
= rect
.Top
;
3104 ncp
.rgrc1
.right
= rect
.Right
;
3105 ncp
.rgrc1
.bottom
= rect
.Bottom
;
3107 Marshal
.StructureToPtr (ncp
, ptr
, true);
3108 NativeWindow
.WndProc (hwnd
.client_window
, Msg
.WM_NCCALCSIZE
, (IntPtr
)1, ptr
);
3109 ncp
= (XplatUIWin32
.NCCALCSIZE_PARAMS
)Marshal
.PtrToStructure (ptr
, typeof(XplatUIWin32
.NCCALCSIZE_PARAMS
));
3110 Marshal
.FreeHGlobal (ptr
);
3112 // FIXME - debug this with Menus, need to set hwnd.ClientRect
3114 rect
= new Rectangle (ncp
.rgrc1
.left
, ncp
.rgrc1
.top
, ncp
.rgrc1
.right
- ncp
.rgrc1
.left
, ncp
.rgrc1
.bottom
- ncp
.rgrc1
.top
);
3115 //Console.WriteLine("CreateOffscreenbuffer...");
3116 // CreateOffscreenBuffer (ref hwnd.client_offscreen, rect.Width, rect.Height);
3118 XMoveResizeWindow (DisplayHandle
, hwnd
.client_window
, rect
.X
, rect
.Y
, rect
.Width
, rect
.Height
);
3120 goto ProcessNextMessage
;
3123 msg
.lParam
= IntPtr
.Zero
; // FIXME - Generate LPWINDOWPOS structure and pass on
3127 case XEventName
.FocusIn
: {
3128 if (!hwnd
.Enabled
) {
3129 goto ProcessNextMessage
;
3131 msg
.message
= Msg
.WM_SETFOCUS
;
3132 msg
.wParam
= IntPtr
.Zero
;
3136 case XEventName
.FocusOut
: {
3137 if (!hwnd
.Enabled
) {
3138 goto ProcessNextMessage
;
3140 msg
.message
= Msg
.WM_KILLFOCUS
;
3141 msg
.wParam
= IntPtr
.Zero
;
3145 case XEventName
.Expose
: {
3146 if (PostQuitState
) {
3147 goto ProcessNextMessage
;
3152 if (!hwnd
.expose_pending
) {
3153 goto ProcessNextMessage
;
3156 if (!hwnd
.nc_expose_pending
) {
3157 goto ProcessNextMessage
;
3160 switch (hwnd
.border_style
) {
3161 case FormBorderStyle
.Fixed3D
: {
3164 g
= Graphics
.FromHwnd (hwnd
.whole_window
);
3165 ControlPaint
.DrawBorder3D (g
, new Rectangle (0, 0, hwnd
.Width
, hwnd
.Height
));
3170 case FormBorderStyle
.FixedSingle
: {
3173 g
= Graphics
.FromHwnd (hwnd
.whole_window
);
3174 ControlPaint
.DrawBorder (g
, new Rectangle (0, 0, hwnd
.Width
, hwnd
.Height
), Color
.Black
, ButtonBorderStyle
.Solid
);
3179 #if DriverDebugExtra
3180 Console
.WriteLine("GetMessage(): Window {0:X} Exposed non-client area {1},{2} {3}x{4}", hwnd
.client_window
.ToInt32(), xevent
.ExposeEvent
.x
, xevent
.ExposeEvent
.y
, xevent
.ExposeEvent
.width
, xevent
.ExposeEvent
.height
);
3183 Rectangle rect
= new Rectangle (xevent
.ExposeEvent
.x
, xevent
.ExposeEvent
.y
, xevent
.ExposeEvent
.width
, xevent
.ExposeEvent
.height
);
3184 Region region
= new Region (rect
);
3185 IntPtr hrgn
= region
.GetHrgn (null); // Graphics object isn't needed
3186 msg
.message
= Msg
.WM_NCPAINT
;
3188 hwnd
.nc_expose_pending
= false;
3191 #if DriverDebugExtra
3192 Console
.WriteLine("GetMessage(): Window {0:X} Exposed area {1},{2} {3}x{4}", hwnd
.client_window
.ToInt32(), xevent
.ExposeEvent
.x
, xevent
.ExposeEvent
.y
, xevent
.ExposeEvent
.width
, xevent
.ExposeEvent
.height
);
3194 if (Caret
.Visible
== 1) {
3195 Caret
.Paused
= true;
3199 if (Caret
.Visible
== 1) {
3201 Caret
.Paused
= false;
3203 msg
.message
= Msg
.WM_PAINT
;
3207 case XEventName
.DestroyNotify
: {
3209 // This is a bit tricky, we don't receive our own DestroyNotify, we only get those for our children
3210 hwnd
= Hwnd
.ObjectFromHandle (xevent
.DestroyWindowEvent
.window
);
3212 // We may get multiple for the same window, act only one the first (when Hwnd still knows about it)
3213 if (hwnd
.client_window
== xevent
.DestroyWindowEvent
.window
) {
3214 msg
.hwnd
= hwnd
.client_window
;
3215 msg
.message
= Msg
.WM_DESTROY
;
3219 Console
.WriteLine("Got DestroyNotify on Window {0:X}", msg
.hwnd
.ToInt32());
3222 goto ProcessNextMessage
;
3228 case XEventName
.ClientMessage
: {
3229 if (Dnd
.HandleClientMessage (ref xevent
)) {
3230 goto ProcessNextMessage
;
3233 if (xevent
.ClientMessageEvent
.message_type
== (IntPtr
)AsyncAtom
) {
3234 XplatUIDriverSupport
.ExecuteClientMessage ((GCHandle
)xevent
.ClientMessageEvent
.ptr1
);
3238 if (xevent
.ClientMessageEvent
.message_type
== (IntPtr
)HoverState
.Atom
) {
3239 msg
.message
= Msg
.WM_MOUSEHOVER
;
3240 msg
.wParam
= GetMousewParam (0);
3241 msg
.lParam
= (IntPtr
) (xevent
.ClientMessageEvent
.ptr1
);
3245 if (xevent
.ClientMessageEvent
.message_type
== (IntPtr
)PostAtom
) {
3246 msg
.hwnd
= xevent
.ClientMessageEvent
.ptr1
;
3247 msg
.message
= (Msg
) xevent
.ClientMessageEvent
.ptr2
.ToInt32 ();
3248 msg
.wParam
= xevent
.ClientMessageEvent
.ptr3
;
3249 msg
.lParam
= xevent
.ClientMessageEvent
.ptr4
;
3254 if (xevent
.ClientMessageEvent
.message_type
== (IntPtr
)NetAtoms
[(int)NA
._XEMBED
]) {
3255 Console
.WriteLine("GOT EMBED MESSAGE {0:X}", xevent
.ClientMessageEvent
.ptr2
.ToInt32());
3260 if (xevent
.ClientMessageEvent
.message_type
== (IntPtr
)NetAtoms
[(int)NA
.WM_PROTOCOLS
]) {
3261 if (xevent
.ClientMessageEvent
.ptr1
== (IntPtr
)NetAtoms
[(int)NA
.WM_DELETE_WINDOW
]) {
3262 msg
.message
= Msg
.WM_CLOSE
;
3263 Graphics
.FromHdcInternal (IntPtr
.Zero
);
3267 // We should not get this, but I'll leave the code in case we need it in the future
3268 if (xevent
.ClientMessageEvent
.ptr1
== (IntPtr
)NetAtoms
[(int)NA
.WM_TAKE_FOCUS
]) {
3269 goto ProcessNextMessage
;
3275 case XEventName
.TimerNotify
: {
3276 xevent
.TimerNotifyEvent
.handler (this, EventArgs
.Empty
);
3281 goto ProcessNextMessage
;
3288 internal override bool GetText (IntPtr handle
, out string text
)
3292 textptr
= IntPtr
.Zero
;
3295 // FIXME - use _NET properties
3296 XFetchName (DisplayHandle
, Hwnd
.ObjectFromHandle (handle
).whole_window
, ref textptr
);
3298 if (textptr
!= IntPtr
.Zero
) {
3299 text
= Marshal
.PtrToStringAnsi (textptr
);
3308 internal override void GetWindowPos (IntPtr handle
, bool is_toplevel
, out int x
, out int y
, out int width
, out int height
, out int client_width
, out int client_height
)
3313 hwnd
= Hwnd
.ObjectFromHandle (handle
);
3319 height
= hwnd
.height
;
3321 rect
= Hwnd
.GetClientRectangle (hwnd
.border_style
, hwnd
.menu
, hwnd
.title_style
, hwnd
.caption_height
, hwnd
.tool_caption_height
, width
, height
);
3323 client_width
= rect
.Width
;
3324 client_height
= rect
.Height
;
3329 // Should we throw an exception or fail silently?
3330 // throw new ArgumentException("Called with an invalid window handle", "handle");
3340 internal override FormWindowState
GetWindowState (IntPtr handle
)
3346 IntPtr prop
= IntPtr
.Zero
;
3350 XWindowAttributes attributes
;
3353 hwnd
= Hwnd
.ObjectFromHandle (handle
);
3357 XGetWindowProperty (DisplayHandle
, hwnd
.whole_window
, NetAtoms
[(int)NA
._NET_WM_STATE
], 0, 256, false, Atom
.XA_ATOM
, out actual_atom
, out actual_format
, out nitems
, out bytes_after
, ref prop
);
3358 if ((nitems
> 0) && (prop
!= IntPtr
.Zero
)) {
3359 for (int i
= 0; i
< nitems
; i
++) {
3360 atom
= (IntPtr
)Marshal
.ReadInt32 (prop
, i
* 4);
3361 if ((atom
== (IntPtr
)NetAtoms
[(int)NA
._NET_WM_STATE_MAXIMIZED_HORZ
]) || (atom
== (IntPtr
)NetAtoms
[(int)NA
._NET_WM_STATE_MAXIMIZED_VERT
])) {
3363 } else if (atom
== (IntPtr
)NetAtoms
[(int)NA
._NET_WM_STATE_HIDDEN
]) {
3371 return FormWindowState
.Minimized
;
3372 } else if (maximized
== 2) {
3373 return FormWindowState
.Maximized
;
3376 attributes
= new XWindowAttributes ();
3377 XGetWindowAttributes (DisplayHandle
, handle
, ref attributes
);
3378 if (attributes
.map_state
== MapState
.IsUnmapped
) {
3379 throw new NotSupportedException ("Cannot retrieve the state of an unmapped window");
3383 return FormWindowState
.Normal
;
3386 internal override void GrabInfo (out IntPtr handle
, out bool GrabConfined
, out Rectangle GrabArea
)
3389 GrabConfined
= Grab
.Confined
;
3390 GrabArea
= Grab
.Area
;
3393 internal override void GrabWindow (IntPtr handle
, IntPtr confine_to_handle
)
3396 IntPtr confine_to_window
;
3398 confine_to_window
= IntPtr
.Zero
;
3400 if (confine_to_handle
!= IntPtr
.Zero
) {
3401 XWindowAttributes attributes
= new XWindowAttributes ();
3403 hwnd
= Hwnd
.ObjectFromHandle (confine_to_handle
);
3406 XGetWindowAttributes (DisplayHandle
, hwnd
.client_window
, ref attributes
);
3408 Grab
.Area
.X
= attributes
.x
;
3409 Grab
.Area
.Y
= attributes
.y
;
3410 Grab
.Area
.Width
= attributes
.width
;
3411 Grab
.Area
.Height
= attributes
.height
;
3412 Grab
.Confined
= true;
3413 confine_to_window
= hwnd
.client_window
;
3418 hwnd
= Hwnd
.ObjectFromHandle (handle
);
3421 XGrabPointer (DisplayHandle
, hwnd
.client_window
, false,
3422 EventMask
.ButtonPressMask
| EventMask
.ButtonMotionMask
|
3423 EventMask
.ButtonReleaseMask
| EventMask
.PointerMotionMask
,
3424 GrabMode
.GrabModeAsync
, GrabMode
.GrabModeAsync
, confine_to_window
, 0, 0);
3428 internal override void UngrabWindow (IntPtr hwnd
)
3431 XUngrabPointer (DisplayHandle
, 0);
3432 XFlush (DisplayHandle
);
3434 Grab
.Hwnd
= IntPtr
.Zero
;
3435 Grab
.Confined
= false;
3438 internal override void HandleException (Exception e
)
3440 StackTrace st
= new StackTrace (e
, true);
3441 Console
.WriteLine ("Exception '{0}'", e
.Message
+ st
.ToString ());
3442 Console
.WriteLine ("{0}{1}", e
.Message
, st
.ToString ());
3445 internal override void Invalidate (IntPtr handle
, Rectangle rc
, bool clear
)
3450 hwnd
= Hwnd
.ObjectFromHandle (handle
);
3453 xevent
= new XEvent ();
3454 xevent
.type
= XEventName
.Expose
;
3455 xevent
.ExposeEvent
.display
= DisplayHandle
;
3456 xevent
.ExposeEvent
.window
= hwnd
.client_window
;
3459 xevent
.ExposeEvent
.x
= hwnd
.X
;
3460 xevent
.ExposeEvent
.y
= hwnd
.Y
;
3461 xevent
.ExposeEvent
.width
= hwnd
.Width
;
3462 xevent
.ExposeEvent
.height
= hwnd
.Height
;
3464 xevent
.ExposeEvent
.x
= rc
.X
;
3465 xevent
.ExposeEvent
.y
= rc
.Y
;
3466 xevent
.ExposeEvent
.width
= rc
.Width
;
3467 xevent
.ExposeEvent
.height
= rc
.Height
;
3473 internal override bool IsEnabled (IntPtr handle
)
3475 return Hwnd
.ObjectFromHandle (handle
).Enabled
;
3478 internal override bool IsVisible (IntPtr handle
)
3480 return Hwnd
.ObjectFromHandle (handle
).visible
;
3483 internal override void KillTimer (Timer timer
)
3486 TimerList
.Remove (timer
);
3490 internal override void MenuToScreen (IntPtr handle
, ref int x
, ref int y
)
3497 hwnd
= Hwnd
.ObjectFromHandle (handle
);
3500 XTranslateCoordinates (DisplayHandle
, hwnd
.whole_window
, RootWindow
, x
, y
, out dest_x_return
, out dest_y_return
, out child
);
3507 internal override void OverrideCursor (IntPtr cursor
)
3509 OverrideCursorHandle
= cursor
;
3512 internal override PaintEventArgs
PaintEventStart (IntPtr handle
, bool client
)
3514 PaintEventArgs paint_event
;
3517 hwnd
= Hwnd
.ObjectFromHandle (handle
);
3519 if (Caret
.Visible
== 1) {
3520 Caret
.Paused
= true;
3525 // handle backing store
3526 IntPtr gdk_window
= gdk_window_lookup (hwnd
.client_window
);
3527 IntPtr gdk_pixmap
= NewPixmap (gdk_window
, hwnd
.ClientRect
.Width
, hwnd
.ClientRect
.Height
);
3529 backing_store
[gdk_window
] = gdk_pixmap
;
3531 hwnd
.client_dc
= Graphics
.FromHwnd (gdk_x11_drawable_get_xid (gdk_pixmap
));
3532 hwnd
.client_dc
.SetClip (hwnd
.invalid
);
3533 paint_event
= new PaintEventArgs (hwnd
.client_dc
, hwnd
.invalid
);
3534 hwnd
.expose_pending
= false;
3538 hwnd
.client_dc
= Graphics
.FromHwnd (hwnd
.whole_window
);
3539 paint_event
= new PaintEventArgs (hwnd
.client_dc
, new Rectangle (0, 0, hwnd
.width
, hwnd
.height
));
3540 hwnd
.nc_expose_pending
= false;
3546 internal override void PaintEventEnd (IntPtr handle
, bool client
)
3550 hwnd
= Hwnd
.ObjectFromHandle (handle
);
3552 hwnd
.client_dc
.Flush ();
3555 // clients are already drawn to a backing store pixmap
3556 IntPtr gdk_window
= gdk_window_lookup (hwnd
.client_window
);
3557 IntPtr gdk_pixmap
= (IntPtr
)backing_store
[gdk_window
];
3559 BlitOffscreenPixmap (gdk_pixmap
, gdk_window
, hwnd
.Invalid
);
3561 g_object_unref (gdk_pixmap
);
3562 backing_store
.Remove (gdk_pixmap
);
3564 hwnd
.ClearInvalidArea ();
3567 hwnd
.client_dc
.Dispose ();
3568 hwnd
.client_dc
= null;
3570 if (Caret
.Visible
== 1) {
3572 Caret
.Paused
= false;
3576 internal override bool PeekMessage (ref MSG msg
, IntPtr hWnd
, int wFilterMin
, int wFilterMax
, uint flags
)
3580 // FIXME - imlement filtering
3582 if ((flags
& (uint)PeekMessageFlags
.PM_REMOVE
) == 0) {
3583 throw new NotImplementedException ("PeekMessage PM_NOREMOVE is not implemented yet"); // FIXME - Implement PM_NOREMOVE flag
3587 if (MessageQueue
.Count
> 0) {
3590 // Only call UpdateMessageQueue if real events are pending
3591 // otherwise we go to sleep on the socket
3592 if (XPending (DisplayHandle
) != 0) {
3593 UpdateMessageQueue ();
3598 CheckTimers (DateTime
.Now
);
3603 return GetMessage (ref msg
, hWnd
, wFilterMin
, wFilterMax
);
3606 // FIXME - I think this should just enqueue directly
3607 internal override bool PostMessage (IntPtr handle
, Msg message
, IntPtr wparam
, IntPtr lparam
)
3609 XEvent xevent
= new XEvent ();
3610 Hwnd hwnd
= Hwnd
.ObjectFromHandle (handle
);
3612 xevent
.type
= XEventName
.ClientMessage
;
3613 xevent
.ClientMessageEvent
.display
= DisplayHandle
;
3616 xevent
.ClientMessageEvent
.window
= hwnd
.whole_window
;
3618 xevent
.ClientMessageEvent
.window
= IntPtr
.Zero
;
3621 xevent
.ClientMessageEvent
.message_type
= (IntPtr
) PostAtom
;
3622 xevent
.ClientMessageEvent
.format
= 32;
3623 xevent
.ClientMessageEvent
.ptr1
= handle
;
3624 xevent
.ClientMessageEvent
.ptr2
= (IntPtr
) message
;
3625 xevent
.ClientMessageEvent
.ptr3
= wparam
;
3626 xevent
.ClientMessageEvent
.ptr4
= lparam
;
3628 MessageQueue
.Enqueue (xevent
);
3633 internal override void PostQuitMessage (int exitCode
)
3635 XFlush (DisplayHandle
);
3636 PostQuitState
= true;
3638 // Remove our display handle from S.D
3639 Graphics
.FromHdcInternal (IntPtr
.Zero
);
3642 internal override void ScreenToClient (IntPtr handle
, ref int x
, ref int y
)
3649 hwnd
= Hwnd
.ObjectFromHandle (handle
);
3652 XTranslateCoordinates (DisplayHandle
, RootWindow
, hwnd
.client_window
, x
, y
, out dest_x_return
, out dest_y_return
, out child
);
3659 internal override void ScreenToMenu (IntPtr handle
, ref int x
, ref int y
)
3666 hwnd
= Hwnd
.ObjectFromHandle (handle
);
3669 XTranslateCoordinates (DisplayHandle
, RootWindow
, hwnd
.whole_window
, x
, y
, out dest_x_return
, out dest_y_return
, out child
);
3676 internal override void ScrollWindow (IntPtr handle
, Rectangle area
, int XAmount
, int YAmount
, bool with_children
)
3680 XGCValues gc_values
;
3682 hwnd
= Hwnd
.ObjectFromHandle (handle
);
3684 if (hwnd
.invalid
!= Rectangle
.Empty
) {
3685 // BIG FAT WARNING. This only works with how we use this function right now
3686 // where we basically still scroll the whole window, but work around areas
3687 // that are covered by our children
3689 hwnd
.invalid
.X
+= XAmount
;
3690 hwnd
.invalid
.Y
+= YAmount
;
3692 if (hwnd
.invalid
.X
< 0) {
3693 hwnd
.invalid
.Width
+= hwnd
.invalid
.X
;
3697 if (hwnd
.invalid
.Y
< 0) {
3698 hwnd
.invalid
.Height
+= hwnd
.invalid
.Y
;
3703 gc_values
= new XGCValues ();
3705 if (with_children
) {
3706 gc_values
.subwindow_mode
= GCSubwindowMode
.IncludeInferiors
;
3709 gc
= XCreateGC (DisplayHandle
, hwnd
.client_window
, 0, ref gc_values
);
3711 XCopyArea (DisplayHandle
, hwnd
.client_window
, hwnd
.client_window
, gc
, area
.X
- XAmount
, area
.Y
- YAmount
, area
.Width
, area
.Height
, area
.X
, area
.Y
);
3713 // Generate an expose for the area exposed by the horizontal scroll
3715 hwnd
.AddInvalidArea (area
.X
, area
.Y
, XAmount
, area
.Height
);
3716 } else if (XAmount
< 0) {
3717 hwnd
.AddInvalidArea (XAmount
+ area
.X
+ area
.Width
, area
.Y
, -XAmount
, area
.Height
);
3720 // Generate an expose for the area exposed by the vertical scroll
3722 hwnd
.AddInvalidArea (area
.X
, area
.Y
, area
.Width
, YAmount
);
3723 } else if (YAmount
< 0) {
3724 hwnd
.AddInvalidArea (area
.X
, YAmount
+ area
.Y
+ area
.Height
, area
.Width
, -YAmount
);
3726 XFreeGC (DisplayHandle
, gc
);
3728 UpdateWindow (handle
);
3731 internal override void ScrollWindow (IntPtr handle
, int XAmount
, int YAmount
, bool with_children
)
3735 hwnd
= Hwnd
.GetObjectFromWindow (handle
);
3737 ScrollWindow (handle
, hwnd
.ClientRect
, XAmount
, YAmount
, with_children
);
3740 internal override void SendAsyncMethod (AsyncMethodData method
)
3742 XEvent xevent
= new XEvent ();
3744 xevent
.type
= XEventName
.ClientMessage
;
3745 xevent
.ClientMessageEvent
.display
= DisplayHandle
;
3746 xevent
.ClientMessageEvent
.window
= FosterParent
;
3747 xevent
.ClientMessageEvent
.message_type
= (IntPtr
)AsyncAtom
;
3748 xevent
.ClientMessageEvent
.format
= 32;
3749 xevent
.ClientMessageEvent
.ptr1
= (IntPtr
) GCHandle
.Alloc (method
);
3751 MessageQueue
.EnqueueLocked (xevent
);
3756 internal override IntPtr
SendMessage (IntPtr hwnd
, Msg message
, IntPtr wParam
, IntPtr lParam
)
3758 return NativeWindow
.WndProc (hwnd
, message
, wParam
, lParam
);
3761 internal override void SetAllowDrop (IntPtr handle
, bool value)
3763 // We allow drop on all windows
3766 internal override DragDropEffects
StartDrag (IntPtr handle
, object data
,
3767 DragDropEffects allowed_effects
)
3769 Hwnd hwnd
= Hwnd
.ObjectFromHandle (handle
);
3772 throw new ArgumentException ("Attempt to begin drag from invalid window handle (" + handle
.ToInt32 () + ").");
3774 return Dnd
.StartDrag (hwnd
.client_window
, data
, allowed_effects
);
3777 internal override void SetBorderStyle (IntPtr handle
, FormBorderStyle border_style
)
3781 hwnd
= Hwnd
.ObjectFromHandle (handle
);
3783 hwnd
.border_style
= border_style
;
3785 XMoveResizeWindow (DisplayHandle
, hwnd
.client_window
, hwnd
.ClientRect
.X
, hwnd
.ClientRect
.Y
, hwnd
.ClientRect
.Width
, hwnd
.ClientRect
.Height
);
3787 InvalidateWholeWindow (handle
);
3790 internal override void SetCaretPos (IntPtr handle
, int x
, int y
)
3792 if (Caret
.Hwnd
== handle
) {
3793 Caret
.Timer
.Stop ();
3799 if (Caret
.Visible
== 1) {
3801 Caret
.Timer
.Start ();
3806 internal override void SetCursor (IntPtr handle
, IntPtr cursor
)
3810 if (OverrideCursorHandle
== IntPtr
.Zero
) {
3811 if ((LastCursorWindow
== handle
) && (LastCursorHandle
== cursor
)) {
3815 LastCursorHandle
= cursor
;
3816 LastCursorWindow
= handle
;
3818 hwnd
= Hwnd
.ObjectFromHandle (handle
);
3820 if (cursor
!= IntPtr
.Zero
) {
3821 XDefineCursor (DisplayHandle
, hwnd
.whole_window
, cursor
);
3823 XUndefineCursor (DisplayHandle
, hwnd
.whole_window
);
3829 hwnd
= Hwnd
.ObjectFromHandle (handle
);
3831 XDefineCursor (DisplayHandle
, hwnd
.whole_window
, OverrideCursorHandle
);
3835 internal override void SetCursorPos (IntPtr handle
, int x
, int y
)
3837 if (handle
== IntPtr
.Zero
) {
3839 XWarpPointer (DisplayHandle
, IntPtr
.Zero
, IntPtr
.Zero
, 0, 0, 0, 0, x
, y
);
3845 hwnd
= Hwnd
.ObjectFromHandle (handle
);
3847 XWarpPointer (DisplayHandle
, IntPtr
.Zero
, hwnd
.client_window
, 0, 0, 0, 0, x
, y
);
3853 internal override void SetFocus (IntPtr handle
)
3857 hwnd
= Hwnd
.ObjectFromHandle (handle
);
3859 if (FocusWindow
!= IntPtr
.Zero
) {
3860 PostMessage (FocusWindow
, Msg
.WM_KILLFOCUS
, hwnd
.client_window
, IntPtr
.Zero
);
3862 PostMessage (hwnd
.client_window
, Msg
.WM_SETFOCUS
, FocusWindow
, IntPtr
.Zero
);
3863 FocusWindow
= hwnd
.client_window
;
3865 //XSetInputFocus(DisplayHandle, Hwnd.ObjectFromHandle(handle).client_window, RevertTo.None, IntPtr.Zero);
3868 internal override void SetIcon (IntPtr handle
, Icon icon
)
3872 hwnd
= Hwnd
.ObjectFromHandle (handle
);
3874 SetIcon (hwnd
, icon
);
3878 internal override void SetMenu (IntPtr handle
, Menu menu
)
3882 hwnd
= Hwnd
.ObjectFromHandle (handle
);
3885 // FIXME - do we need to trigger some resize?
3888 internal override void SetModal (IntPtr handle
, bool Modal
)
3891 ModalWindows
.Push (handle
);
3893 if (ModalWindows
.Contains (handle
)) {
3894 ModalWindows
.Pop ();
3896 if (ModalWindows
.Count
> 0) {
3897 Activate ((IntPtr
)ModalWindows
.Peek ());
3902 internal override IntPtr
SetParent (IntPtr handle
, IntPtr parent
)
3906 hwnd
= Hwnd
.ObjectFromHandle (handle
);
3907 hwnd
.parent
= Hwnd
.ObjectFromHandle (parent
);
3911 Console
.WriteLine("Parent for window {0:X} / {1:X} = {2:X} (Handle:{3:X})", hwnd
.ClientWindow
.ToInt32(), hwnd
.WholeWindow
.ToInt32(), hwnd
.parent
!= null ? hwnd
.parent
.Handle
.ToInt32() : 0, parent
.ToInt32());
3913 XReparentWindow (DisplayHandle
, hwnd
.whole_window
, hwnd
.parent
.client_window
, hwnd
.x
, hwnd
.y
);
3919 internal override void SetTimer (Timer timer
)
3922 TimerList
.Add (timer
);
3927 internal override bool SetTopmost (IntPtr handle
, IntPtr handle_owner
, bool enabled
)
3932 hwnd
= Hwnd
.ObjectFromHandle (handle
);
3934 if (handle_owner
!= IntPtr
.Zero
) {
3935 hwnd_owner
= Hwnd
.ObjectFromHandle (handle_owner
);
3942 if (hwnd_owner
!= null) {
3943 XSetTransientForHint (DisplayHandle
, hwnd
.whole_window
, hwnd_owner
.whole_window
);
3945 XSetTransientForHint (DisplayHandle
, hwnd
.whole_window
, FosterParent
);
3950 XDeleteProperty (DisplayHandle
, hwnd
.whole_window
, (int)Atom
.XA_WM_TRANSIENT_FOR
);
3956 internal override bool SetVisible (IntPtr handle
, bool visible
)
3960 hwnd
= Hwnd
.ObjectFromHandle (handle
);
3961 hwnd
.visible
= visible
;
3965 if (Control
.FromHandle (handle
) is Form
) {
3968 s
= ((Form
)Control
.FromHandle (handle
)).WindowState
;
3970 XMapWindow (DisplayHandle
, hwnd
.whole_window
);
3971 XMapWindow (DisplayHandle
, hwnd
.client_window
);
3974 case FormWindowState
.Minimized
: SetWindowState (handle
, FormWindowState
.Minimized
); break;
3975 case FormWindowState
.Maximized
: SetWindowState (handle
, FormWindowState
.Maximized
); break;
3978 XMapWindow (DisplayHandle
, hwnd
.whole_window
);
3979 XMapWindow (DisplayHandle
, hwnd
.client_window
);
3982 XUnmapWindow (DisplayHandle
, hwnd
.whole_window
);
3988 internal override void SetWindowMinMax (IntPtr handle
, Rectangle maximized
, Size min
, Size max
)
3993 hwnd
= Hwnd
.ObjectFromHandle (handle
);
3998 hints
= new XSizeHints ();
4000 if (min
!= Size
.Empty
) {
4001 hints
.flags
= (IntPtr
)((int)hints
.flags
| (int)XSizeHintsFlags
.PMinSize
);
4002 hints
.min_width
= min
.Width
;
4003 hints
.min_height
= min
.Height
;
4006 if (max
!= Size
.Empty
) {
4007 hints
.flags
= (IntPtr
)((int)hints
.flags
| (int)XSizeHintsFlags
.PMaxSize
);
4008 hints
.max_width
= max
.Width
;
4009 hints
.max_height
= max
.Height
;
4012 XSetWMNormalHints (DisplayHandle
, hwnd
.whole_window
, ref hints
);
4014 if (maximized
!= Rectangle
.Empty
) {
4015 hints
.flags
= (IntPtr
)XSizeHintsFlags
.PPosition
;
4016 hints
.x
= maximized
.X
;
4017 hints
.y
= maximized
.Y
;
4018 hints
.width
= maximized
.Width
;
4019 hints
.height
= maximized
.Height
;
4021 // Metacity does not seem to follow this constraint for maximized (zoomed) windows
4022 XSetZoomHints (DisplayHandle
, hwnd
.whole_window
, ref hints
);
4027 internal override void SetWindowPos (IntPtr handle
, int x
, int y
, int width
, int height
)
4030 Rectangle client_rect
;
4032 hwnd
= Hwnd
.ObjectFromHandle (handle
);
4034 // X requires a sanity check for width & height; otherwise it dies
4035 if (hwnd
.zero_sized
&& width
> 0 && height
> 0) {
4037 XMapWindow (DisplayHandle
, hwnd
.whole_window
);
4039 hwnd
.zero_sized
= false;
4043 hwnd
.zero_sized
= true;
4044 XUnmapWindow (DisplayHandle
, hwnd
.whole_window
);
4048 hwnd
.zero_sized
= true;
4049 XUnmapWindow (DisplayHandle
, hwnd
.whole_window
);
4052 client_rect
= Hwnd
.GetClientRectangle (hwnd
.border_style
, hwnd
.menu
, hwnd
.title_style
, hwnd
.caption_height
, hwnd
.tool_caption_height
, width
, height
);
4054 // Save a server roundtrip (and prevent a feedback loop)
4055 if ((hwnd
.x
== x
) && (hwnd
.y
== y
) &&
4056 (hwnd
.width
== width
) && (hwnd
.height
== height
) &&
4057 (hwnd
.ClientRect
== client_rect
)) {
4061 if (!hwnd
.zero_sized
) {
4063 XMoveResizeWindow (DisplayHandle
, hwnd
.whole_window
, x
, y
, width
, height
);
4064 XMoveResizeWindow (DisplayHandle
, hwnd
.client_window
, client_rect
.X
, client_rect
.Y
, client_rect
.Width
, client_rect
.Height
);
4068 // Prevent an old queued ConfigureNotify from setting our width with outdated data, set it now
4070 hwnd
.height
= height
;
4073 internal override void SetWindowState (IntPtr handle
, FormWindowState state
)
4075 FormWindowState current_state
;
4078 hwnd
= Hwnd
.ObjectFromHandle (handle
);
4080 current_state
= GetWindowState (handle
);
4082 if (current_state
== state
) {
4087 case FormWindowState
.Normal
: {
4089 if (current_state
== FormWindowState
.Minimized
) {
4090 XMapWindow (DisplayHandle
, hwnd
.whole_window
);
4091 XMapWindow (DisplayHandle
, hwnd
.client_window
);
4092 } else if (current_state
== FormWindowState
.Maximized
) {
4093 SendNetWMMessage (hwnd
.whole_window
, (IntPtr
)(uint)NetAtoms
[(int)NA
._NET_WM_STATE
], (IntPtr
)2 /* toggle */, (IntPtr
)NetAtoms
[(int)NA
._NET_WM_STATE_MAXIMIZED_HORZ
], (IntPtr
)NetAtoms
[(int)NA
._NET_WM_STATE_MAXIMIZED_VERT
]);
4100 case FormWindowState
.Minimized
: {
4102 if (current_state
== FormWindowState
.Maximized
) {
4103 SendNetWMMessage (hwnd
.whole_window
, (IntPtr
)NetAtoms
[(int)NA
._NET_WM_STATE
], (IntPtr
)2 /* toggle */, (IntPtr
)NetAtoms
[(int)NA
._NET_WM_STATE_MAXIMIZED_HORZ
], (IntPtr
)NetAtoms
[(int)NA
._NET_WM_STATE_MAXIMIZED_VERT
]);
4105 XIconifyWindow (DisplayHandle
, hwnd
.whole_window
, ScreenNo
);
4110 case FormWindowState
.Maximized
: {
4112 if (current_state
== FormWindowState
.Minimized
) {
4113 XMapWindow (DisplayHandle
, hwnd
.whole_window
);
4114 XMapWindow (DisplayHandle
, hwnd
.client_window
);
4117 SendNetWMMessage (hwnd
.whole_window
, (IntPtr
)NetAtoms
[(int)NA
._NET_WM_STATE
], (IntPtr
)1 /* Add */, (IntPtr
)NetAtoms
[(int)NA
._NET_WM_STATE_MAXIMIZED_HORZ
], (IntPtr
)NetAtoms
[(int)NA
._NET_WM_STATE_MAXIMIZED_VERT
]);
4125 internal override void SetWindowStyle (IntPtr handle
, CreateParams cp
)
4129 hwnd
= Hwnd
.ObjectFromHandle (handle
);
4130 SetHwndStyles (hwnd
, cp
);
4131 SetWMStyles (hwnd
, cp
);
4134 internal override void SetWindowTransparency (IntPtr handle
, double transparency
, Color key
)
4139 hwnd
= Hwnd
.ObjectFromHandle (handle
);
4145 hwnd
.opacity
= (uint)(0xffffffff * transparency
);
4146 opacity
= hwnd
.opacity
;
4148 if (hwnd
.reparented
) {
4149 XChangeProperty (DisplayHandle
, XGetParent (hwnd
.whole_window
), NetAtoms
[(int)NA
._NET_WM_WINDOW_OPACITY
], Atom
.XA_CARDINAL
, 32, PropertyMode
.Replace
, ref opacity
, 1);
4153 internal override bool SetZOrder (IntPtr handle
, IntPtr after_handle
, bool top
, bool bottom
)
4155 Hwnd hwnd
= Hwnd
.ObjectFromHandle (handle
);
4159 XRaiseWindow (DisplayHandle
, hwnd
.whole_window
);
4162 } else if (!bottom
) {
4163 Hwnd after_hwnd
= null;
4165 if (after_handle
!= IntPtr
.Zero
) {
4166 after_hwnd
= Hwnd
.ObjectFromHandle (after_handle
);
4169 XWindowChanges values
= new XWindowChanges ();
4171 if (after_hwnd
== null) {
4172 throw new ArgumentNullException ("after_handle", "Need sibling to adjust z-order");
4174 values
.sibling
= after_hwnd
.whole_window
;
4175 values
.stack_mode
= StackMode
.Below
;
4178 XConfigureWindow (DisplayHandle
, hwnd
.whole_window
, ChangeWindowFlags
.CWStackMode
| ChangeWindowFlags
.CWSibling
, ref values
);
4183 XLowerWindow (DisplayHandle
, hwnd
.whole_window
);
4190 internal override void ShowCursor (bool show
)
4192 ; // FIXME - X11 doesn't 'hide' the cursor. we could create an empty cursor
4195 internal override void StartLoop (Thread thread
)
4197 // Future place for prepping a new queue for this specific thread
4200 internal override bool SupportsTransparency ()
4202 // We need to check if the x compositing manager is running
4206 internal override bool SystrayAdd (IntPtr handle
, string tip
, Icon icon
, out ToolTip tt
)
4208 GetSystrayManagerWindow ();
4210 if (SystrayMgrWindow
!= IntPtr
.Zero
) {
4212 XSizeHints size_hints
;
4215 hwnd
= Hwnd
.ObjectFromHandle (handle
);
4217 Console
.WriteLine("Adding Systray Whole:{0:X}, Client:{1:X}", hwnd
.whole_window
.ToInt32(), hwnd
.client_window
.ToInt32());
4220 XUnmapWindow (DisplayHandle
, hwnd
.whole_window
);
4221 XUnmapWindow (DisplayHandle
, hwnd
.client_window
);
4224 gdk_window_destroy (gdk_window_lookup (hwnd
.client_window
));
4225 hwnd
.client_window
= hwnd
.whole_window
;
4227 size_hints
= new XSizeHints ();
4229 size_hints
.flags
= (IntPtr
)(XSizeHintsFlags
.PMinSize
| XSizeHintsFlags
.PMaxSize
| XSizeHintsFlags
.PBaseSize
);
4230 size_hints
.min_width
= icon
.Width
;
4231 size_hints
.min_height
= icon
.Height
;
4233 size_hints
.max_width
= icon
.Width
;
4234 size_hints
.max_height
= icon
.Height
;
4236 size_hints
.base_width
= icon
.Width
;
4237 size_hints
.base_height
= icon
.Height
;
4238 XSetWMNormalHints (DisplayHandle
, hwnd
.whole_window
, ref size_hints
);
4240 atoms
= new uint [2];
4241 atoms
[0] = 1; // Version 1
4242 atoms
[1] = 0; // We're not mapped
4244 // This line cost me 3 days...
4245 XChangeProperty (DisplayHandle
, hwnd
.whole_window
, NetAtoms
[(int)NA
._XEMBED_INFO
], NetAtoms
[(int)NA
._XEMBED_INFO
], 32, PropertyMode
.Replace
, atoms
, 2);
4247 // Need to pick some reasonable defaults
4248 tt
= new ToolTip ();
4249 tt
.AutomaticDelay
= 100;
4250 tt
.InitialDelay
= 250;
4251 tt
.ReshowDelay
= 250;
4252 tt
.ShowAlways
= true;
4254 if ((tip
!= null) && (tip
!= string.Empty
)) {
4255 tt
.SetToolTip (Control
.FromHandle (handle
), tip
);
4261 // Make sure the window exists
4262 XSync (DisplayHandle
, hwnd
.whole_window
);
4264 SendNetClientMessage (SystrayMgrWindow
, (IntPtr
)NetAtoms
[(int)NA
._NET_SYSTEM_TRAY_OPCODE
], IntPtr
.Zero
, (IntPtr
)SystrayRequest
.SYSTEM_TRAY_REQUEST_DOCK
, hwnd
.whole_window
);
4272 internal override bool SystrayChange (IntPtr handle
, string tip
, Icon icon
, ref ToolTip tt
)
4276 control
= Control
.FromHandle (handle
);
4277 if (control
!= null && tt
!= null) {
4278 tt
.SetToolTip (control
, tip
);
4286 internal override void SystrayRemove (IntPtr handle
, ref ToolTip tt
)
4290 hwnd
= Hwnd
.ObjectFromHandle (handle
);
4292 XUnmapWindow (DisplayHandle
, hwnd
.whole_window
);
4293 SetParent (hwnd
.whole_window
, FosterParent
);
4295 // The caller can now re-dock it later...
4302 internal override bool Text (IntPtr handle
, string text
)
4305 gdk_window_set_title (gdk_window_lookup (Hwnd
.ObjectFromHandle (handle
).whole_window
), text
);
4310 internal override bool TranslateMessage (ref MSG msg
)
4312 return Keyboard
.TranslateMessage (ref msg
);
4315 internal override void UpdateWindow (IntPtr handle
)
4320 hwnd
= Hwnd
.ObjectFromHandle (handle
);
4322 if (!hwnd
.visible
|| hwnd
.expose_pending
) {
4327 SendMessage(handle
, Msg
.WM_PAINT
, IntPtr
.Zero
, IntPtr
.Zero
);
4329 xevent
= new XEvent ();
4330 xevent
.type
= XEventName
.Expose
;
4331 xevent
.ExposeEvent
.display
= DisplayHandle
;
4332 xevent
.ExposeEvent
.window
= hwnd
.client_window
;
4334 MessageQueue
.Enqueue (xevent
);
4335 hwnd
.expose_pending
= true;
4339 internal static IntPtr
NewPixmap (IntPtr gdk_window
, int width
, int height
)
4341 return gdk_pixmap_new (gdk_window
, width
, height
, 24); // FIXME: instead of 24, get the correct display depth
4344 internal static void BlitOffscreenPixmap (IntPtr gdk_pixmap
, IntPtr dest_drawable
, Rectangle area
)
4346 IntPtr gdk_gc
= gdk_gc_new (gdk_pixmap
);
4348 gdk_draw_drawable (dest_drawable
, gdk_gc
, gdk_pixmap
, area
.X
, area
.Y
, area
.X
, area
.Y
, area
.Width
, area
.Height
);
4350 g_object_unref (gdk_gc
);
4352 #endregion // Public Static Methods
4355 internal override event EventHandler Idle
;
4356 #endregion // Events
4359 [DllImport ("libX11", EntryPoint
="XSynchronize")]
4360 internal extern static IntPtr
XSynchronize (IntPtr display
, bool onoff
);
4362 [DllImport ("libX11", EntryPoint
="XCreateWindow")]
4363 internal extern static IntPtr
XCreateWindow (IntPtr display
, IntPtr parent
, int x
, int y
, int width
, int height
, int border_width
, int depth
, int xclass
, IntPtr visual
, SetWindowValuemask valuemask
, ref XSetWindowAttributes attributes
);
4364 [DllImport ("libX11", EntryPoint
="XCreateSimpleWindow")]
4365 internal extern static IntPtr
XCreateSimpleWindow (IntPtr display
, IntPtr parent
, int x
, int y
, int width
, int height
, int border_width
, int border
, int background
);
4366 [DllImport ("libX11", EntryPoint
="XMapWindow")]
4367 internal extern static int XMapWindow (IntPtr display
, IntPtr window
);
4368 [DllImport ("libX11", EntryPoint
="XUnmapWindow")]
4369 internal extern static int XUnmapWindow (IntPtr display
, IntPtr window
);
4370 [DllImport ("libX11", EntryPoint
="XMapSubwindows")]
4371 internal extern static int XMapSubindows (IntPtr display
, IntPtr window
);
4372 [DllImport ("libX11", EntryPoint
="XUnmapSubwindows")]
4373 internal extern static int XUnmapSubwindows (IntPtr display
, IntPtr window
);
4374 [DllImport ("libX11", EntryPoint
="XRootWindow")]
4375 internal extern static IntPtr
XRootWindow (IntPtr display
, int screen_number
);
4376 [DllImport ("libX11", EntryPoint
="XNextEvent")]
4377 internal extern static IntPtr
XNextEvent (IntPtr display
, ref XEvent xevent
);
4378 [DllImport ("libX11")]
4379 internal extern static int XConnectionNumber (IntPtr diplay
);
4380 [DllImport ("libX11")]
4381 internal extern static int XPending (IntPtr diplay
);
4382 [DllImport ("libX11")]
4383 internal extern static bool XCheckWindowEvent (IntPtr display
, IntPtr window
, EventMask mask
, ref XEvent xevent
);
4384 [DllImport ("libX11")]
4385 internal extern static bool XCheckMaskEvent (IntPtr display
, EventMask mask
, ref XEvent xevent
);
4386 [DllImport ("libX11", EntryPoint
="XSelectInput")]
4387 internal extern static IntPtr
XSelectInput (IntPtr display
, IntPtr window
, EventMask mask
);
4389 [DllImport ("libX11", EntryPoint
="XReparentWindow")]
4390 internal extern static int XReparentWindow (IntPtr display
, IntPtr window
, IntPtr parent
, int x
, int y
);
4391 [DllImport ("libX11", EntryPoint
="XMoveResizeWindow")]
4392 internal extern static int XMoveResizeWindow (IntPtr display
, IntPtr window
, int x
, int y
, int width
, int height
);
4394 [DllImport ("libX11", EntryPoint
="XResizeWindow")]
4395 internal extern static int XResizeWindow (IntPtr display
, IntPtr window
, int width
, int height
);
4397 [DllImport ("libX11", EntryPoint
="XGetWindowAttributes")]
4398 internal extern static int XGetWindowAttributes (IntPtr display
, IntPtr window
, ref XWindowAttributes attributes
);
4400 [DllImport ("libX11", EntryPoint
="XFlush")]
4401 internal extern static int XFlush (IntPtr display
);
4403 [DllImport ("libX11", EntryPoint
="XSetWMName")]
4404 internal extern static int XSetWMName (IntPtr display
, IntPtr window
, ref XTextProperty text_prop
);
4406 [DllImport ("libX11", EntryPoint
="XStoreName")]
4407 internal extern static int XStoreName (IntPtr display
, IntPtr window
, string window_name
);
4409 [DllImport ("libX11", EntryPoint
="XFetchName")]
4410 internal extern static int XFetchName (IntPtr display
, IntPtr window
, ref IntPtr window_name
);
4412 [DllImport ("libX11", EntryPoint
="XSendEvent")]
4413 internal extern static int XSendEvent (IntPtr display
, IntPtr window
, bool propagate
, EventMask event_mask
, ref XEvent send_event
);
4415 [DllImport ("libX11", EntryPoint
="XQueryTree")]
4416 internal extern static int XQueryTree (IntPtr display
, IntPtr window
, out IntPtr root_return
, out IntPtr parent_return
, out IntPtr children_return
, out int nchildren_return
);
4418 [DllImport ("libX11", EntryPoint
="XFree")]
4419 internal extern static int XFree (IntPtr data
);
4421 [DllImport ("libX11", EntryPoint
="XRaiseWindow")]
4422 internal extern static int XRaiseWindow (IntPtr display
, IntPtr window
);
4424 [DllImport ("libX11", EntryPoint
="XLowerWindow")]
4425 internal extern static uint XLowerWindow (IntPtr display
, IntPtr window
);
4427 [DllImport ("libX11", EntryPoint
="XConfigureWindow")]
4428 internal extern static uint XConfigureWindow (IntPtr display
, IntPtr window
, ChangeWindowFlags value_mask
, ref XWindowChanges values
);
4430 [DllImport ("libX11", EntryPoint
="XInternAtom")]
4431 internal extern static int XInternAtom (IntPtr display
, string atom_name
, bool only_if_exists
);
4433 [DllImport ("libX11", EntryPoint
="XSetWMProtocols")]
4434 internal extern static int XSetWMProtocols (IntPtr display
, IntPtr window
, uint[] protocols
, int count
);
4436 [DllImport ("libX11", EntryPoint
="XGrabPointer")]
4437 internal extern static int XGrabPointer (IntPtr display
, IntPtr window
, bool owner_events
, EventMask event_mask
, GrabMode pointer_mode
, GrabMode keyboard_mode
, IntPtr confine_to
, uint cursor
, uint timestamp
);
4439 [DllImport ("libX11", EntryPoint
="XUngrabPointer")]
4440 internal extern static int XUngrabPointer (IntPtr display
, uint timestamp
);
4442 [DllImport ("libX11", EntryPoint
="XQueryPointer")]
4443 internal extern static bool XQueryPointer (IntPtr display
, IntPtr window
, out IntPtr root
, out IntPtr child
, out int root_x
, out int root_y
, out int win_x
, out int win_y
, out int keys_buttons
);
4445 [DllImport ("libX11", EntryPoint
="XTranslateCoordinates")]
4446 internal extern static bool XTranslateCoordinates (IntPtr display
, IntPtr src_w
, IntPtr dest_w
, int src_x
, int src_y
, out int intdest_x_return
, out int dest_y_return
, out IntPtr child_return
);
4448 [DllImport ("libX11", EntryPoint
="XWarpPointer")]
4449 internal extern static uint XWarpPointer (IntPtr display
, IntPtr src_w
, IntPtr dest_w
, int src_x
, int src_y
, uint src_width
, uint src_height
, int dest_x
, int dest_y
);
4451 [DllImport ("libX11", EntryPoint
="XClearWindow")]
4452 internal extern static int XClearWindow (IntPtr display
, IntPtr window
);
4454 [DllImport ("libX11", EntryPoint
="XClearArea")]
4455 internal extern static int XClearArea (IntPtr display
, IntPtr window
, int x
, int y
, int width
, int height
, bool exposures
);
4458 [DllImport ("libX11", EntryPoint
="XDefaultScreenOfDisplay")]
4459 internal extern static IntPtr
XDefaultScreenOfDisplay (IntPtr display
);
4461 [DllImport ("libX11", EntryPoint
="XScreenNumberOfScreen")]
4462 internal extern static int XScreenNumberOfScreen (IntPtr display
, IntPtr Screen
);
4464 [DllImport ("libX11", EntryPoint
="XDefaultVisual")]
4465 internal extern static IntPtr
XDefaultVisual (IntPtr display
, int screen_number
);
4467 [DllImport ("libX11", EntryPoint
="XDefaultDepth")]
4468 internal extern static uint XDefaultDepth (IntPtr display
, int screen_number
);
4470 [DllImport ("libX11", EntryPoint
="XDefaultColormap")]
4471 internal extern static IntPtr
XDefaultColormap (IntPtr display
, int screen_number
);
4473 [DllImport ("libX11", EntryPoint
="XLookupColor")]
4474 internal extern static int XLookupColor (IntPtr display
, IntPtr Colormap
, string Coloranem
, ref XColor exact_def_color
, ref XColor screen_def_color
);
4476 [DllImport ("libX11", EntryPoint
="XAllocColor")]
4477 internal extern static int XAllocColor (IntPtr display
, IntPtr Colormap
, ref XColor colorcell_def
);
4479 [DllImport ("libX11", EntryPoint
="XSetTransientForHint")]
4480 internal extern static int XSetTransientForHint (IntPtr display
, IntPtr window
, IntPtr prop_window
);
4482 [DllImport ("libX11", EntryPoint
="XChangeProperty")]
4483 internal extern static int XChangeProperty (IntPtr display
, IntPtr window
, int property
, int type
, int format
, PropertyMode mode
, ref MotifWmHints data
, int nelements
);
4485 [DllImport ("libX11", EntryPoint
="XChangeProperty")]
4486 internal extern static int XChangeProperty (IntPtr display
, IntPtr window
, int property
, Atom format
, int type
, PropertyMode mode
, uint[] atoms
, int nelements
);
4488 [DllImport ("libX11", EntryPoint
="XChangeProperty")]
4489 internal extern static int XChangeProperty (IntPtr display
, IntPtr window
, int property
, Atom format
, int type
, PropertyMode mode
, ref uint value, int nelements
);
4491 [DllImport ("libX11", EntryPoint
="XChangeProperty")]
4492 internal extern static int XChangeProperty (IntPtr display
, IntPtr window
, int property
, int format
, int type
, PropertyMode mode
, uint[] atoms
, int nelements
);
4494 [DllImport ("libX11", EntryPoint
="XChangeProperty")]
4495 internal extern static int XChangeProperty (IntPtr display
, IntPtr window
, int property
, int format
, int type
, PropertyMode mode
, IntPtr atoms
, int nelements
);
4497 [DllImport ("libX11", EntryPoint
="XChangeProperty")]
4498 internal extern static int XChangeProperty (IntPtr display
, IntPtr window
, int property
, Atom format
, int type
, PropertyMode mode
, IntPtr atoms
, int nelements
);
4500 [DllImport ("libX11", EntryPoint
="XChangeProperty", CharSet
=CharSet
.Ansi
)]
4501 internal extern static int XChangeProperty (IntPtr display
, IntPtr window
, int property
, int type
, int format
, PropertyMode mode
, string text
, int text_length
);
4503 [DllImport ("libX11", EntryPoint
="XDeleteProperty")]
4504 internal extern static int XDeleteProperty (IntPtr display
, IntPtr window
, int property
);
4506 [DllImport ("gdiplus", EntryPoint
="GetFontMetrics")]
4507 internal extern static bool GetFontMetrics (IntPtr graphicsObject
, IntPtr nativeObject
, out int ascent
, out int descent
);
4510 [DllImport ("libX11", EntryPoint
="XCreateGC")]
4511 internal extern static IntPtr
XCreateGC (IntPtr display
, IntPtr window
, GCFunction valuemask
, ref XGCValues values
);
4513 [DllImport ("libX11", EntryPoint
="XFreeGC")]
4514 internal extern static int XFreeGC (IntPtr display
, IntPtr gc
);
4516 [DllImport ("libX11", EntryPoint
="XSetFunction")]
4517 internal extern static int XSetFunction (IntPtr display
, IntPtr gc
, GXFunction function
);
4519 [DllImport ("libX11", EntryPoint
="XDrawLine")]
4520 internal extern static int XDrawLine (IntPtr display
, IntPtr drawable
, IntPtr gc
, int x1
, int y1
, int x2
, int y2
);
4522 [DllImport ("libX11", EntryPoint
="XDrawRectangle")]
4523 internal extern static int XDrawRectangle (IntPtr display
, IntPtr drawable
, IntPtr gc
, int x1
, int y1
, int width
, int height
);
4525 [DllImport ("libX11", EntryPoint
="XSetWindowBackground")]
4526 internal extern static int XSetWindowBackground (IntPtr display
, IntPtr window
, IntPtr background
);
4528 [DllImport ("libX11", EntryPoint
="XCopyArea")]
4529 internal extern static int XCopyArea (IntPtr display
, IntPtr src
, IntPtr dest
, IntPtr gc
, int src_x
, int src_y
, int width
, int height
, int dest_x
, int dest_y
);
4531 [DllImport ("libX11", EntryPoint
="XGetAtomName")]
4532 internal extern static string XGetAtomName (IntPtr display
, int atom
);
4534 [DllImport ("libX11", EntryPoint
="XGetWindowProperty")]
4535 internal extern static int XGetWindowProperty (IntPtr display
, IntPtr window
, int atom
, int long_offset
, int long_length
, bool delete
, Atom req_type
, out Atom actual_type
, out int actual_format
, out int nitems
, out int bytes_after
, ref IntPtr prop
);
4537 [DllImport ("libX11", EntryPoint
="XSetInputFocus")]
4538 internal extern static int XSetInputFocus (IntPtr display
, IntPtr window
, RevertTo revert_to
, IntPtr time
);
4540 [DllImport ("libX11", EntryPoint
="XIconifyWindow")]
4541 internal extern static int XIconifyWindow (IntPtr display
, IntPtr window
, int screen_number
);
4543 [DllImport ("libX11", EntryPoint
="XDefineCursor")]
4544 internal extern static int XDefineCursor (IntPtr display
, IntPtr window
, IntPtr cursor
);
4546 [DllImport ("libX11", EntryPoint
="XUndefineCursor")]
4547 internal extern static int XUndefineCursor (IntPtr display
, IntPtr window
);
4549 [DllImport ("libX11", EntryPoint
="XFreeCursor")]
4550 internal extern static int XFreeCursor (IntPtr display
, IntPtr cursor
);
4552 [DllImport ("libX11", EntryPoint
="XCreateFontCursor")]
4553 internal extern static IntPtr
XCreateFontCursor (IntPtr display
, CursorFontShape shape
);
4555 [DllImport ("libX11", EntryPoint
="XCreatePixmapCursor")]
4556 internal extern static IntPtr
XCreatePixmapCursor (IntPtr display
, IntPtr source
, IntPtr mask
, ref XColor foreground_color
, ref XColor background_color
, int x_hot
, int y_hot
);
4558 [DllImport ("libX11", EntryPoint
="XCreatePixmapFromBitmapData")]
4559 internal extern static IntPtr
XCreatePixmapFromBitmapData (IntPtr display
, IntPtr drawable
, byte[] data
, int width
, int height
, IntPtr fg
, IntPtr bg
, int depth
);
4561 [DllImport ("libX11", EntryPoint
="XFreePixmap")]
4562 internal extern static IntPtr
XFreePixmap (IntPtr display
, IntPtr pixmap
);
4564 [DllImport ("libX11", EntryPoint
="XWhitePixel")]
4565 internal extern static IntPtr
XWhitePixel (IntPtr display
, int screen_no
);
4567 [DllImport ("libX11", EntryPoint
="XBlackPixel")]
4568 internal extern static IntPtr
XBlackPixel (IntPtr display
, int screen_no
);
4570 [DllImport ("libX11", EntryPoint
="XGrabServer")]
4571 internal extern static void XGrabServer (IntPtr display
);
4573 [DllImport ("libX11", EntryPoint
="XUngrabServer")]
4574 internal extern static void XUngrabServer (IntPtr display
);
4576 [DllImport ("libX11", EntryPoint
="XSetWMNormalHints")]
4577 internal extern static void XSetWMNormalHints (IntPtr display
, IntPtr window
, ref XSizeHints hints
);
4579 [DllImport ("libX11", EntryPoint
="XSetZoomHints")]
4580 internal extern static void XSetZoomHints (IntPtr display
, IntPtr window
, ref XSizeHints hints
);
4582 [DllImport ("libX11", EntryPoint
="XSetWMHints")]
4583 internal extern static void XSetWMHints (IntPtr display
, IntPtr window
, ref XWMHints wmhints
);
4585 [DllImport ("libX11", EntryPoint
="XSync")]
4586 internal extern static void XSync (IntPtr display
, IntPtr window
);
4588 [DllImport ("libX11", EntryPoint
="XGetIconSizes")]
4589 internal extern static int XGetIconSizes (IntPtr display
, IntPtr window
, out IntPtr size_list
, out int count
);
4591 [DllImport ("libX11", EntryPoint
="XSetErrorHandler")]
4592 internal extern static IntPtr
XSetErrorHandler (XErrorHandler error_handler
);
4594 [DllImport ("libX11", EntryPoint
="XGetErrorText")]
4595 internal extern static IntPtr
XGetErrorText (IntPtr display
, byte code
, StringBuilder buffer
, int length
);
4597 [DllImport ("libX11", EntryPoint
="XInitThreads")]
4598 internal extern static int XInitThreads ();
4600 [DllImport ("libX11", EntryPoint
="XConvertSelection")]
4601 internal extern static int XConvertSelection (IntPtr display
, int selection
, int target
, int property
, IntPtr requestor
, IntPtr time
);
4603 [DllImport ("libX11", EntryPoint
="XGetSelectionOwner")]
4604 internal extern static IntPtr
XGetSelectionOwner (IntPtr display
, int selection
);
4606 [DllImport ("libX11", EntryPoint
="XSetSelectionOwner")]
4607 internal extern static int XSetSelectionOwner (IntPtr display
, int selection
, IntPtr owner
, IntPtr time
);
4609 [DllImport ("libX11", EntryPoint
="XSetPlaneMask")]
4610 internal extern static int XSetPlaneMask (IntPtr display
, IntPtr gc
, uint mask
);
4612 [DllImport ("libX11", EntryPoint
="XSetForeground")]
4613 internal extern static int XSetForeground (IntPtr display
, IntPtr gc
, uint foreground
);
4615 [DllImport ("libX11", EntryPoint
="XSetBackground")]
4616 internal extern static int XSetBackground (IntPtr display
, IntPtr gc
, uint background
);
4621 [DllImport("libgdk-x11-2.0.so")]
4622 static extern bool gdk_init_check (IntPtr argc
, IntPtr argv
);
4624 [DllImport("libgdk-x11-2.0.so")]
4625 internal static extern IntPtr
gdk_x11_display_get_xdisplay (IntPtr display
);
4627 [DllImport("libgdk-x11-2.0.so")]
4628 internal static extern IntPtr
gdk_display_get_default ();
4630 [DllImport("libgdk-x11-2.0.so")]
4631 static extern IntPtr
gdk_pixmap_new (IntPtr drawable
, int width
, int height
, int depth
);
4633 [DllImport("libgdk-x11-2.0.so")]
4634 static extern IntPtr
gdk_x11_drawable_get_xid (IntPtr gdkdrawable
);
4636 [DllImport("libgdk-x11-2.0.so")]
4637 static extern void gdk_draw_drawable (IntPtr drawable_dest
, IntPtr gdk_gc
, IntPtr drawable_src
, int xsrc
, int ysrc
, int xdest
, int ydest
, int width
, int height
);
4639 [DllImport("libgdk-x11-2.0.so")]
4640 static extern IntPtr
gdk_gc_new (IntPtr drawable
);
4642 [DllImport("libgdk-x11-2.0.so")]
4643 static extern IntPtr
gdk_window_foreign_new (IntPtr anid
);
4645 [DllImport("libgdk-x11-2.0.so")]
4646 static extern IntPtr
gdk_x11_lookup_xdisplay (IntPtr xdisplay
);
4648 [DllImport("libgdk-x11-2.0.so")]
4649 static extern void gdk_display_close (IntPtr display
);
4651 [DllImport("libgdk-x11-2.0.so")]
4652 static extern void gdk_display_beep (IntPtr display
);
4654 [DllImport("libgdk-x11-2.0.so")]
4655 static extern void gdk_display_sync (IntPtr display
);
4657 [DllImport("libgdk-x11-2.0.so")]
4658 static extern IntPtr
gdk_get_default_root_window ();
4660 [DllImport("libgdk-x11-2.0.so")]
4661 static extern IntPtr
gdk_colormap_get_system ();
4663 [DllImport("libgdk-x11-2.0.so")]
4664 static extern IntPtr
gdk_x11_colormap_get_xcolormap (IntPtr gdk_colormap
);
4666 [DllImport("libgdk-x11-2.0.so")]
4667 static extern void gdk_window_destroy (IntPtr gdk_window
);
4669 [DllImport("libgdk-x11-2.0.so")]
4670 static extern void gdk_x11_grab_server ();
4672 [DllImport("libgdk-x11-2.0.so")]
4673 static extern void gdk_x11_ungrab_server ();
4675 [DllImport("libgdk-x11-2.0.so")]
4676 static extern void gdk_display_flush (IntPtr gdk_display
);
4678 [DllImport("libgdk-x11-2.0.so")]
4679 static extern void gdk_window_iconify (IntPtr gdk_window
);
4681 [DllImport("libgdk-x11-2.0.so")]
4682 static extern void gdk_window_deiconify (IntPtr gdk_window
);
4684 [DllImport("libgdk-x11-2.0.so")]
4685 static extern void gdk_window_set_decorations (IntPtr gdk_window
, int decorations
);
4687 [DllImport("libgdk-x11-2.0.so")]
4688 static extern IntPtr
gdk_screen_get_default ();
4690 [DllImport("libgdk-x11-2.0.so")]
4691 static extern int gdk_screen_get_number (IntPtr gdk_screen
);
4693 [DllImport("libgdk-x11-2.0.so")]
4694 static extern IntPtr
gdk_window_lookup (IntPtr anid
);
4696 [DllImport("libgdk-x11-2.0.so")]
4697 static extern IntPtr
gdk_window_new (IntPtr gdk_parent
, ref GdkWindowAttr gdk_window_attributes
, int attributes_mask
);
4699 [DllImport("libgdk-x11-2.0.so")]
4700 static extern void gdk_window_set_events (IntPtr gdk_window
, int event_mask
);
4702 [DllImport("libgdk-x11-2.0.so")]
4703 static extern void gdk_window_show (IntPtr window
);
4705 [DllImport("libgdk-x11-2.0.so")]
4706 static extern void gdk_window_set_title (IntPtr gdk_window
, string title
);
4708 [DllImport("libgdk-x11-2.0.so")]
4709 static extern int gdk_window_get_origin (IntPtr gdk_window
, out int x
, out int y
);
4711 [DllImport("libgdk-x11-2.0.so")]
4712 static extern void gdk_window_get_geometry (IntPtr gdk_window
, out int x
, out int y
, out int width
, out int height
, out int depth
);
4714 [DllImport("libgdk-x11-2.0.so")]
4715 static extern void gdk_property_change (IntPtr gdk_window
, /*GdkAtom*/IntPtr property
, /*GdkAtom*/IntPtr type
, int format
, int gdk_prop_mode
, /*const guchar **/ IntPtr data
, int nelements
);
4717 [DllImport("libgdk-x11-2.0.so")]
4718 static extern IntPtr
gdk_window_get_parent (IntPtr gdk_window
);
4720 [DllImport("libgdk-x11-2.0.so")]
4721 static extern void gdk_display_get_maximal_cursor_size (IntPtr gdk_display
, out uint width
, out uint height
);
4723 [DllImport("libgdk-x11-2.0.so")]
4724 static extern int gdk_visual_get_best_depth ();
4727 #region gobject imports
4728 [DllImport("libglib-2.0.so")]
4729 static extern void g_free (IntPtr mem
);
4731 [DllImport("libgobject-2.0.so")]
4732 static extern void g_object_unref (IntPtr nativeObject
);