PageRenderTime 121ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 1ms

/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11GTK.cs

https://bitbucket.org/danipen/mono
C# | 4732 lines | 3616 code | 894 blank | 222 comment | 662 complexity | e0883dca3567277fc2ace0937d6d8fd2 MD5 | raw file
Possible License(s): Unlicense, Apache-2.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
  1. // Permission is hereby granted, free of charge, to any person obtaining
  2. // a copy of this software and associated documentation files (the
  3. // "Software"), to deal in the Software without restriction, including
  4. // without limitation the rights to use, copy, modify, merge, publish,
  5. // distribute, sublicense, and/or sell copies of the Software, and to
  6. // permit persons to whom the Software is furnished to do so, subject to
  7. // the following conditions:
  8. //
  9. // The above copyright notice and this permission notice shall be
  10. // included in all copies or substantial portions of the Software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  13. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  14. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  15. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  16. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  17. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  18. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  19. //
  20. // Copyright (c) 2004-2006 Novell, Inc.
  21. //
  22. // Authors:
  23. // Peter Bartok pbartok@novell.com
  24. // Alexander Olk alex.olk@googlemail.com
  25. //
  26. //
  27. // NOTE:
  28. // This driver understands the following environment variables: (Set the var to enable feature)
  29. //
  30. // MONO_XEXCEPTIONS = throw an exception when a X11 error is encountered;
  31. // by default a message is displayed but execution continues
  32. //
  33. // MONO_XSYNC = perform all X11 commands synchronous; this is slower but
  34. // helps in debugging errors
  35. //
  36. // NOT COMPLETE - WORK IN PROGRESS
  37. // One feature of the driver is, that PaintEventstart returns a graphics context created from a offscreen drawable (pixmap)
  38. // define to log Window handles and relationships to stdout
  39. #undef DriverDebug
  40. // Extra detailed debug
  41. #undef DriverDebugExtra
  42. using System;
  43. using System.ComponentModel;
  44. using System.Collections;
  45. using System.Diagnostics;
  46. using System.Drawing;
  47. using System.Drawing.Drawing2D;
  48. using System.Drawing.Imaging;
  49. using System.IO;
  50. using System.Net;
  51. using System.Net.Sockets;
  52. using System.Reflection;
  53. using System.Runtime.InteropServices;
  54. using System.Text;
  55. using System.Threading;
  56. // Only do the poll when building with mono for now
  57. #if __MonoCS__
  58. using Mono.Unix.Native;
  59. #endif
  60. /// X11 Version
  61. namespace System.Windows.Forms {
  62. internal class XplatUIX11GTK : XplatUIDriver {
  63. internal enum GdkWindowClass {
  64. GDK_INPUT_OUTPUT,
  65. GDK_INPUT_ONLY
  66. }
  67. internal enum GdkWindowType {
  68. GDK_WINDOW_ROOT,
  69. GDK_WINDOW_TOPLEVEL,
  70. GDK_WINDOW_CHILD,
  71. GDK_WINDOW_DIALOG,
  72. GDK_WINDOW_TEMP,
  73. GDK_WINDOW_FOREIGN
  74. }
  75. internal enum GdkWindowHints {
  76. GDK_HINT_POS = 1 << 0,
  77. GDK_HINT_MIN_SIZE = 1 << 1,
  78. GDK_HINT_MAX_SIZE = 1 << 2,
  79. GDK_HINT_BASE_SIZE = 1 << 3,
  80. GDK_HINT_ASPECT = 1 << 4,
  81. GDK_HINT_RESIZE_INC = 1 << 5,
  82. GDK_HINT_WIN_GRAVITY = 1 << 6,
  83. GDK_HINT_USER_POS = 1 << 7,
  84. GDK_HINT_USER_SIZE = 1 << 8
  85. }
  86. internal enum GdkGravity {
  87. GDK_GRAVITY_NORTH_WEST = 1,
  88. GDK_GRAVITY_NORTH,
  89. GDK_GRAVITY_NORTH_EAST,
  90. GDK_GRAVITY_WEST,
  91. GDK_GRAVITY_CENTER,
  92. GDK_GRAVITY_EAST,
  93. GDK_GRAVITY_SOUTH_WEST,
  94. GDK_GRAVITY_SOUTH,
  95. GDK_GRAVITY_SOUTH_EAST,
  96. GDK_GRAVITY_STATIC
  97. }
  98. internal enum GdkWindowEdge {
  99. GDK_WINDOW_EDGE_NORTH_WEST,
  100. GDK_WINDOW_EDGE_NORTH,
  101. GDK_WINDOW_EDGE_NORTH_EAST,
  102. GDK_WINDOW_EDGE_WEST,
  103. GDK_WINDOW_EDGE_EAST,
  104. GDK_WINDOW_EDGE_SOUTH_WEST,
  105. GDK_WINDOW_EDGE_SOUTH,
  106. GDK_WINDOW_EDGE_SOUTH_EAST
  107. }
  108. internal enum GdkWindowTypeHint {
  109. GDK_WINDOW_TYPE_HINT_NORMAL,
  110. GDK_WINDOW_TYPE_HINT_DIALOG,
  111. GDK_WINDOW_TYPE_HINT_MENU,
  112. GDK_WINDOW_TYPE_HINT_TOOLBAR,
  113. GDK_WINDOW_TYPE_HINT_SPLASHSCREEN,
  114. GDK_WINDOW_TYPE_HINT_UTILITY,
  115. GDK_WINDOW_TYPE_HINT_DOCK,
  116. GDK_WINDOW_TYPE_HINT_DESKTOP
  117. }
  118. internal enum GdkWindowAttributesType {
  119. GDK_WA_TITLE = 1 << 1,
  120. GDK_WA_X = 1 << 2,
  121. GDK_WA_Y = 1 << 3,
  122. GDK_WA_CURSOR = 1 << 4,
  123. GDK_WA_COLORMAP = 1 << 5,
  124. GDK_WA_VISUAL = 1 << 6,
  125. GDK_WA_WMCLASS = 1 << 7,
  126. GDK_WA_NOREDIR = 1 << 8
  127. }
  128. internal enum GdkEventMask {
  129. GDK_EXPOSURE_MASK = 1 << 1,
  130. GDK_POINTER_MOTION_MASK = 1 << 2,
  131. GDK_POINTER_MOTION_HINT_MASK = 1 << 3,
  132. GDK_BUTTON_MOTION_MASK = 1 << 4,
  133. GDK_BUTTON1_MOTION_MASK = 1 << 5,
  134. GDK_BUTTON2_MOTION_MASK = 1 << 6,
  135. GDK_BUTTON3_MOTION_MASK = 1 << 7,
  136. GDK_BUTTON_PRESS_MASK = 1 << 8,
  137. GDK_BUTTON_RELEASE_MASK = 1 << 9,
  138. GDK_KEY_PRESS_MASK = 1 << 10,
  139. GDK_KEY_RELEASE_MASK = 1 << 11,
  140. GDK_ENTER_NOTIFY_MASK = 1 << 12,
  141. GDK_LEAVE_NOTIFY_MASK = 1 << 13,
  142. GDK_FOCUS_CHANGE_MASK = 1 << 14,
  143. GDK_STRUCTURE_MASK = 1 << 15,
  144. GDK_PROPERTY_CHANGE_MASK = 1 << 16,
  145. GDK_VISIBILITY_NOTIFY_MASK = 1 << 17,
  146. GDK_PROXIMITY_IN_MASK = 1 << 18,
  147. GDK_PROXIMITY_OUT_MASK = 1 << 19,
  148. GDK_SUBSTRUCTURE_MASK = 1 << 20,
  149. GDK_SCROLL_MASK = 1 << 21,
  150. GDK_ALL_EVENTS_MASK = 0x3FFFFE
  151. }
  152. internal enum GdkEventType {
  153. GDK_NOTHING = -1,
  154. GDK_DELETE = 0,
  155. GDK_DESTROY = 1,
  156. GDK_EXPOSE = 2,
  157. GDK_MOTION_NOTIFY = 3,
  158. GDK_BUTTON_PRESS = 4,
  159. GDK_2BUTTON_PRESS = 5,
  160. GDK_3BUTTON_PRESS = 6,
  161. GDK_BUTTON_RELEASE = 7,
  162. GDK_KEY_PRESS = 8,
  163. GDK_KEY_RELEASE = 9,
  164. GDK_ENTER_NOTIFY = 10,
  165. GDK_LEAVE_NOTIFY = 11,
  166. GDK_FOCUS_CHANGE = 12,
  167. GDK_CONFIGURE = 13,
  168. GDK_MAP = 14,
  169. GDK_UNMAP = 15,
  170. GDK_PROPERTY_NOTIFY = 16,
  171. GDK_SELECTION_CLEAR = 17,
  172. GDK_SELECTION_REQUEST = 18,
  173. GDK_SELECTION_NOTIFY = 19,
  174. GDK_PROXIMITY_IN = 20,
  175. GDK_PROXIMITY_OUT = 21,
  176. GDK_DRAG_ENTER = 22,
  177. GDK_DRAG_LEAVE = 23,
  178. GDK_DRAG_MOTION = 24,
  179. GDK_DRAG_STATUS = 25,
  180. GDK_DROP_START = 26,
  181. GDK_DROP_FINISHED = 27,
  182. GDK_CLIENT_EVENT = 28,
  183. GDK_VISIBILITY_NOTIFY = 29,
  184. GDK_NO_EXPOSE = 30,
  185. GDK_SCROLL = 31,
  186. GDK_WINDOW_STATE = 32,
  187. GDK_SETTING = 33,
  188. GDK_OWNER_CHANGE = 34,
  189. GDK_GRAB_BROKEN = 35
  190. }
  191. internal enum GdkWMDecoration {
  192. GDK_DECOR_ALL = 1 << 0,
  193. GDK_DECOR_BORDER = 1 << 1,
  194. GDK_DECOR_RESIZEH = 1 << 2,
  195. GDK_DECOR_TITLE = 1 << 3,
  196. GDK_DECOR_MENU = 1 << 4,
  197. GDK_DECOR_MINIMIZE = 1 << 5,
  198. GDK_DECOR_MAXIMIZE = 1 << 6
  199. }
  200. internal enum GdkWMFunction {
  201. GDK_FUNC_ALL = 1 << 0,
  202. GDK_FUNC_RESIZE = 1 << 1,
  203. GDK_FUNC_MOVE = 1 << 2,
  204. GDK_FUNC_MINIMIZE = 1 << 3,
  205. GDK_FUNC_MAXIMIZE = 1 << 4,
  206. GDK_FUNC_CLOSE = 1 << 5
  207. }
  208. internal enum GdkCursorType {
  209. GDK_X_CURSOR = 0,
  210. GDK_ARROW = 2,
  211. GDK_BASED_ARROW_DOWN = 4,
  212. GDK_BASED_ARROW_UP = 6,
  213. GDK_BOAT = 8,
  214. GDK_BOGOSITY = 10,
  215. GDK_BOTTOM_LEFT_CORNER = 12,
  216. GDK_BOTTOM_RIGHT_CORNER = 14,
  217. GDK_BOTTOM_SIDE = 16,
  218. GDK_BOTTOM_TEE = 18,
  219. GDK_BOX_SPIRAL = 20,
  220. GDK_CENTER_PTR = 22,
  221. GDK_CIRCLE = 24,
  222. GDK_CLOCK = 26,
  223. GDK_COFFEE_MUG = 28,
  224. GDK_CROSS = 30,
  225. GDK_CROSS_REVERSE = 32,
  226. GDK_CROSSHAIR = 34,
  227. GDK_DIAMOND_CROSS = 36,
  228. GDK_DOT = 38,
  229. GDK_DOTBOX = 40,
  230. GDK_DOUBLE_ARROW = 42,
  231. GDK_DRAFT_LARGE = 44,
  232. GDK_DRAFT_SMALL = 46,
  233. GDK_DRAPED_BOX = 48,
  234. GDK_EXCHANGE = 50,
  235. GDK_FLEUR = 52,
  236. GDK_GOBBLER = 54,
  237. GDK_GUMBY = 56,
  238. GDK_HAND1 = 58,
  239. GDK_HAND2 = 60,
  240. GDK_HEART = 62,
  241. GDK_ICON = 64,
  242. GDK_IRON_CROSS = 66,
  243. GDK_LEFT_PTR = 68,
  244. GDK_LEFT_SIDE = 70,
  245. GDK_LEFT_TEE = 72,
  246. GDK_LEFTBUTTON = 74,
  247. GDK_LL_ANGLE = 76,
  248. GDK_LR_ANGLE = 78,
  249. GDK_MAN = 80,
  250. GDK_MIDDLEBUTTON = 82,
  251. GDK_MOUSE = 84,
  252. GDK_PENCIL = 86,
  253. GDK_PIRATE = 88,
  254. GDK_PLUS = 90,
  255. GDK_QUESTION_ARROW = 92,
  256. GDK_RIGHT_PTR = 94,
  257. GDK_RIGHT_SIDE = 96,
  258. GDK_RIGHT_TEE = 98,
  259. GDK_RIGHTBUTTON = 100,
  260. GDK_RTL_LOGO = 102,
  261. GDK_SAILBOAT = 104,
  262. GDK_SB_DOWN_ARROW = 106,
  263. GDK_SB_H_DOUBLE_ARROW = 108,
  264. GDK_SB_LEFT_ARROW = 110,
  265. GDK_SB_RIGHT_ARROW = 112,
  266. GDK_SB_UP_ARROW = 114,
  267. GDK_SB_V_DOUBLE_ARROW = 116,
  268. GDK_SHUTTLE = 118,
  269. GDK_SIZING = 120,
  270. GDK_SPIDER = 122,
  271. GDK_SPRAYCAN = 124,
  272. GDK_STAR = 126,
  273. GDK_TARGET = 128,
  274. GDK_TCROSS = 130,
  275. GDK_TOP_LEFT_ARROW = 132,
  276. GDK_TOP_LEFT_CORNER = 134,
  277. GDK_TOP_RIGHT_CORNER = 136,
  278. GDK_TOP_SIDE = 138,
  279. GDK_TOP_TEE = 140,
  280. GDK_TREK = 142,
  281. GDK_UL_ANGLE = 144,
  282. GDK_UMBRELLA = 146,
  283. GDK_UR_ANGLE = 148,
  284. GDK_WATCH = 150,
  285. GDK_XTERM = 152,
  286. GDK_LAST_CURSOR,
  287. GDK_CURSOR_IS_PIXMAP = -1
  288. }
  289. internal enum GdkPropMode {
  290. GDK_PROP_MODE_REPLACE,
  291. GDK_PROP_MODE_PREPEND,
  292. GDK_PROP_MODE_APPEND
  293. }
  294. [StructLayout (LayoutKind.Sequential)]
  295. internal struct GdkGeometry {
  296. internal int min_width;
  297. internal int min_height;
  298. internal int max_width;
  299. internal int max_height;
  300. internal int base_width;
  301. internal int base_height;
  302. internal int width_inc;
  303. internal int height_inc;
  304. internal double min_aspect;
  305. internal double max_aspect;
  306. internal GdkGravity win_gravity;
  307. }
  308. [StructLayout (LayoutKind.Sequential)]
  309. internal struct GdkWindowAttr {
  310. internal string title;
  311. internal int event_mask;
  312. internal int x, y;
  313. internal int width;
  314. internal int height;
  315. internal GdkWindowClass wclass;
  316. internal IntPtr visual;
  317. internal IntPtr colormap;
  318. internal GdkWindowType window_type;
  319. internal IntPtr cursor;
  320. internal string wmclass_name;
  321. internal string wmclass_class;
  322. internal bool override_redirect;
  323. }
  324. #region Local Variables
  325. // General
  326. static volatile XplatUIX11GTK Instance;
  327. private static int RefCount;
  328. private static object XlibLock; // Our locking object
  329. private static bool ThemesEnabled;
  330. // General X11
  331. private static IntPtr DisplayHandle; // X11 handle to display
  332. private static IntPtr GdkDisplayHandle; // gdk handle to display
  333. private static int ScreenNo; // Screen number used
  334. private static IntPtr GdkScreen;
  335. private static IntPtr DefaultColormap; // Colormap for screen
  336. private static IntPtr GdkDefaultColormap; // Gdk Colormap for screen
  337. private static IntPtr CustomVisual; // Visual for window creation
  338. private static IntPtr GdkCustomVisual;
  339. private static IntPtr CustomColormap; // Colormap for window creation
  340. private static IntPtr GdkCustomColormap;
  341. private static int VisualBestDepth;
  342. private static IntPtr RootWindow; // Handle of the root window for the screen/display
  343. private static IntPtr GdkRootWindow; // Gdk handle of the root window for the screen/display
  344. private static IntPtr FosterParent; // Container to hold child windows until their parent exists
  345. private static IntPtr GdkFosterParent; // Container to hold child windows until their parent exists
  346. private static XErrorHandler ErrorHandler; // Error handler delegate
  347. private static bool ErrorExceptions; // Throw exceptions on X errors
  348. private static bool PostQuitState; // True if we've got an pending exit
  349. // Clipboard
  350. private static IntPtr ClipMagic = new IntPtr(27051977);
  351. private static ClipboardStruct Clipboard; // Our clipboard
  352. // Communication
  353. private static int PostAtom; // PostMessage atom
  354. private static int AsyncAtom; // Support for async messages
  355. // Message Loop
  356. private static XEventQueue MessageQueue; // Holds our queued up events
  357. #if __MonoCS__ //
  358. private static Pollfd[] pollfds; // For watching the X11 socket
  359. #endif //
  360. private static X11Keyboard Keyboard; //
  361. private static X11Dnd Dnd;
  362. private static Socket listen; //
  363. private static Socket wake; //
  364. private static Socket wake_receive; //
  365. private static byte[] network_buffer; //
  366. // Focus tracking
  367. private static IntPtr ActiveWindow; // Handle of the active window
  368. private static IntPtr FocusWindow; // Handle of the window with keyboard focus (if any)
  369. // Modality support
  370. private static Stack ModalWindows; // Stack of our modal windows
  371. // Systray
  372. private static IntPtr SystrayMgrWindow; // Handle of the Systray Manager window
  373. // Cursors
  374. private static IntPtr LastCursorWindow; // The last window we set the cursor on
  375. private static IntPtr LastCursorHandle; // The handle that was last set on LastCursorWindow
  376. private static IntPtr OverrideCursorHandle; // The cursor that is set to override any other cursors
  377. // Caret
  378. private static CaretStruct Caret; //
  379. // Support for Window Styles
  380. private static int[] NetAtoms; // All atoms we know
  381. // mouse hover message generation
  382. private static HoverStruct HoverState; //
  383. // double click message generation
  384. private static ClickStruct ClickPending; //
  385. // Support for mouse grab
  386. private static GrabStruct Grab; //
  387. // State
  388. private static Point MousePosition; // Last position of mouse, in screen coords
  389. internal static MouseButtons MouseState; // Last state of mouse buttons
  390. // Timers
  391. private static ArrayList TimerList; // Holds SWF.Timers
  392. // 'Constants'
  393. private static int DoubleClickInterval; // msec; max interval between clicks to count as double click
  394. const GdkEventMask GdkSelectInputMask = GdkEventMask.GDK_BUTTON_PRESS_MASK |
  395. GdkEventMask.GDK_BUTTON_RELEASE_MASK |
  396. GdkEventMask.GDK_KEY_PRESS_MASK |
  397. GdkEventMask.GDK_KEY_RELEASE_MASK |
  398. GdkEventMask.GDK_ENTER_NOTIFY_MASK |
  399. GdkEventMask.GDK_LEAVE_NOTIFY_MASK |
  400. GdkEventMask.GDK_EXPOSURE_MASK |
  401. GdkEventMask.GDK_FOCUS_CHANGE_MASK |
  402. GdkEventMask.GDK_POINTER_MOTION_MASK |
  403. GdkEventMask.GDK_VISIBILITY_NOTIFY_MASK |
  404. GdkEventMask.GDK_SUBSTRUCTURE_MASK |
  405. GdkEventMask.GDK_STRUCTURE_MASK;
  406. static readonly object lockobj = new object ();
  407. static Hashtable backing_store = new Hashtable (5);
  408. #endregion // Local Variables
  409. #region Constructors
  410. private XplatUIX11GTK ()
  411. {
  412. Console.WriteLine ("XplatUIX11GTK ctor...");
  413. // Handle singleton stuff first
  414. RefCount = 0;
  415. // init gdk
  416. gdk_init_check (IntPtr.Zero, IntPtr.Zero);
  417. // Now regular initialization
  418. XlibLock = new object ();
  419. MessageQueue = new XEventQueue ();
  420. TimerList = new ArrayList ();
  421. XInitThreads ();
  422. ErrorExceptions = false;
  423. // X11 Initialization
  424. SetDisplay (gdk_x11_display_get_xdisplay (gdk_display_get_default ()));
  425. X11DesktopColors.Initialize ();
  426. // Handle any upcoming errors; we re-set it here, X11DesktopColor stuff might have stolen it (gtk does)
  427. ErrorHandler = new XErrorHandler (HandleError);
  428. XSetErrorHandler (ErrorHandler);
  429. }
  430. #endregion // Constructors
  431. #region Singleton Specific Code
  432. public static XplatUIX11GTK GetInstance ()
  433. {
  434. lock (lockobj) {
  435. if (Instance == null) {
  436. Instance = new XplatUIX11GTK ();
  437. }
  438. RefCount++;
  439. }
  440. return Instance;
  441. }
  442. public int Reference {
  443. get {
  444. return RefCount;
  445. }
  446. }
  447. #endregion
  448. #region Internal Properties
  449. internal static IntPtr Display {
  450. get {
  451. return DisplayHandle;
  452. }
  453. set {
  454. XplatUIX11GTK.GetInstance ().SetDisplay (value);
  455. }
  456. }
  457. internal static int Screen {
  458. get {
  459. return ScreenNo;
  460. }
  461. set {
  462. ScreenNo = value;
  463. }
  464. }
  465. internal static IntPtr RootWindowHandle {
  466. get {
  467. return RootWindow;
  468. }
  469. set {
  470. RootWindow = value;
  471. }
  472. }
  473. internal static IntPtr Visual {
  474. get {
  475. return CustomVisual;
  476. }
  477. set {
  478. CustomVisual = value;
  479. }
  480. }
  481. internal static IntPtr ColorMap {
  482. get {
  483. return CustomColormap;
  484. }
  485. set {
  486. CustomColormap = value;
  487. }
  488. }
  489. #endregion
  490. #region XExceptionClass
  491. internal class XException : ApplicationException {
  492. IntPtr Display;
  493. IntPtr ResourceID;
  494. IntPtr Serial;
  495. XRequest RequestCode;
  496. byte ErrorCode;
  497. byte MinorCode;
  498. public XException (IntPtr Display, IntPtr ResourceID, IntPtr Serial, byte ErrorCode, XRequest RequestCode, byte MinorCode)
  499. {
  500. this.Display = Display;
  501. this.ResourceID = ResourceID;
  502. this.Serial = Serial;
  503. this.RequestCode = RequestCode;
  504. this.ErrorCode = ErrorCode;
  505. this.MinorCode = MinorCode;
  506. }
  507. public override string Message {
  508. get {
  509. return GetMessage (Display, ResourceID, Serial, ErrorCode, RequestCode, MinorCode);
  510. }
  511. }
  512. public static string GetMessage (IntPtr Display, IntPtr ResourceID, IntPtr Serial, byte ErrorCode, XRequest RequestCode, byte MinorCode)
  513. {
  514. StringBuilder sb;
  515. string x_error_text;
  516. string error;
  517. sb = new StringBuilder (160);
  518. XGetErrorText (Display, ErrorCode, sb, sb.Capacity);
  519. x_error_text = sb.ToString ();
  520. 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);
  521. return error;
  522. }
  523. }
  524. #endregion // XExceptionClass
  525. #region Internal Methods
  526. // native X display handle
  527. internal void SetDisplay (IntPtr display_handle)
  528. {
  529. if (display_handle != IntPtr.Zero) {
  530. Hwnd hwnd;
  531. if ((GdkDisplayHandle != IntPtr.Zero) && (GdkFosterParent != IntPtr.Zero)) {
  532. hwnd = Hwnd.ObjectFromHandle (gdk_x11_drawable_get_xid (GdkFosterParent));
  533. gdk_window_destroy (GdkFosterParent);
  534. hwnd.Dispose ();
  535. }
  536. if (GdkDisplayHandle != IntPtr.Zero) {
  537. gdk_display_close (GdkDisplayHandle);
  538. }
  539. DisplayHandle = display_handle;
  540. GdkDisplayHandle = gdk_x11_lookup_xdisplay (display_handle);
  541. // We need to tell System.Drawing our DisplayHandle. FromHdcInternal has
  542. // been hacked to do this for us.
  543. Graphics.FromHdcInternal (DisplayHandle);
  544. // Debugging support
  545. if (Environment.GetEnvironmentVariable ("MONO_XSYNC") != null) {
  546. XSynchronize (DisplayHandle, true);
  547. }
  548. if (Environment.GetEnvironmentVariable ("MONO_XEXCEPTIONS") != null) {
  549. ErrorExceptions = true;
  550. }
  551. // Generic X11 setup
  552. GdkScreen = gdk_screen_get_default ();
  553. // or gdk_x11_get_default_screen
  554. ScreenNo = gdk_screen_get_number (GdkScreen);
  555. GdkRootWindow = gdk_get_default_root_window ();
  556. RootWindow = gdk_x11_drawable_get_xid (GdkRootWindow);
  557. GdkDefaultColormap = gdk_colormap_get_system ();
  558. DefaultColormap = gdk_x11_colormap_get_xcolormap (GdkDefaultColormap);
  559. VisualBestDepth = gdk_visual_get_best_depth ();
  560. //Console.WriteLine (VisualBestDepth);
  561. // Create the foster parent
  562. FosterParent = XCreateSimpleWindow (DisplayHandle, RootWindow, 0, 0, 1, 1, 4, 0, 0);
  563. GdkFosterParent = gdk_window_foreign_new (FosterParent);
  564. if (GdkFosterParent == IntPtr.Zero) {
  565. Console.WriteLine ("XplatUIX11GTK Constructor failed to create FosterParent");
  566. }
  567. hwnd = new Hwnd ();
  568. hwnd.WholeWindow = FosterParent;
  569. hwnd.ClientWindow = FosterParent;
  570. // For sleeping on the X11 socket
  571. listen = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
  572. IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 0);
  573. listen.Bind (ep);
  574. listen.Listen (1);
  575. // To wake up when a timer is ready
  576. network_buffer = new byte [10];
  577. wake = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
  578. wake.Connect (listen.LocalEndPoint);
  579. wake_receive = listen.Accept ();
  580. #if __MonoCS__
  581. pollfds = new Pollfd [2];
  582. pollfds [0] = new Pollfd ();
  583. pollfds [0].fd = XConnectionNumber (DisplayHandle);
  584. pollfds [0].events = PollEvents.POLLIN;
  585. pollfds [1] = new Pollfd ();
  586. pollfds [1].fd = wake_receive.Handle.ToInt32 ();
  587. pollfds [1].events = PollEvents.POLLIN;
  588. #endif
  589. Keyboard = new X11Keyboard (DisplayHandle);
  590. Dnd = new X11Dnd (DisplayHandle);
  591. PostQuitState = false;
  592. DoubleClickInterval = 500;
  593. HoverState.Interval = 500;
  594. HoverState.Timer = new Timer ();
  595. HoverState.Timer.Enabled = false;
  596. HoverState.Timer.Interval = HoverState.Interval;
  597. HoverState.Timer.Tick += new EventHandler (MouseHover);
  598. HoverState.X = -1;
  599. HoverState.Y = -1;
  600. ActiveWindow = IntPtr.Zero;
  601. FocusWindow = IntPtr.Zero;
  602. ModalWindows = new Stack (3);
  603. MouseState = MouseButtons.None;
  604. MousePosition = new Point (0, 0);
  605. Caret.Timer = new Timer ();
  606. Caret.Timer.Interval = 500; // FIXME - where should this number come from?
  607. Caret.Timer.Tick += new EventHandler (CaretCallback);
  608. SetupAtoms ();
  609. // Grab atom changes off the root window to catch certain WM events
  610. gdk_window_set_events (GdkRootWindow, (int)GdkEventMask.GDK_PROPERTY_CHANGE_MASK);
  611. // Handle any upcoming errors
  612. ErrorHandler = new XErrorHandler (HandleError);
  613. XSetErrorHandler (ErrorHandler);
  614. } else {
  615. throw new ArgumentNullException ("Display", "Could not open display (X-Server required. Check you DISPLAY environment variable)");
  616. }
  617. }
  618. #endregion // Internal Methods
  619. #region Private Methods
  620. private static void SetupAtoms ()
  621. {
  622. NetAtoms = new int [(int)NA.LAST_NET_ATOM];
  623. NetAtoms [(int)NA.WM_PROTOCOLS] = XInternAtom (DisplayHandle, "WM_PROTOCOLS", false);
  624. NetAtoms [(int)NA.WM_DELETE_WINDOW] = XInternAtom (DisplayHandle, "WM_DELETE_WINDOW", false);
  625. NetAtoms [(int)NA.WM_TAKE_FOCUS] = XInternAtom (DisplayHandle, "WM_TAKE_FOCUS", false);
  626. NetAtoms [(int)NA._NET_SUPPORTED] = XInternAtom (DisplayHandle, "_NET_SUPPORTED", false);
  627. NetAtoms [(int)NA._NET_CLIENT_LIST] = XInternAtom (DisplayHandle, "_NET_CLIENT_LIST", false);
  628. NetAtoms [(int)NA._NET_NUMBER_OF_DESKTOPS] = XInternAtom (DisplayHandle, "_NET_NUMBER_OF_DESKTOPS", false);
  629. NetAtoms [(int)NA._NET_DESKTOP_GEOMETRY] = XInternAtom (DisplayHandle, "_NET_DESKTOP_GEOMETRY", false);
  630. NetAtoms [(int)NA._NET_DESKTOP_VIEWPORT] = XInternAtom (DisplayHandle, "_NET_DESKTOP_VIEWPORT", false);
  631. NetAtoms [(int)NA._NET_CURRENT_DESKTOP] = XInternAtom (DisplayHandle, "_NET_CURRENT_DESKTOP", false);
  632. NetAtoms [(int)NA._NET_DESKTOP_NAMES] = XInternAtom (DisplayHandle, "_NET_DESKTOP_NAMES", false);
  633. NetAtoms [(int)NA._NET_ACTIVE_WINDOW] = XInternAtom (DisplayHandle, "_NET_ACTIVE_WINDOW", false);
  634. NetAtoms [(int)NA._NET_WORKAREA] = XInternAtom (DisplayHandle, "_NET_WORKAREA", false);
  635. NetAtoms [(int)NA._NET_SUPPORTING_WM_CHECK] = XInternAtom (DisplayHandle, "_NET_SUPPORTING_WM_CHECK", false);
  636. NetAtoms [(int)NA._NET_VIRTUAL_ROOTS] = XInternAtom (DisplayHandle, "_NET_VIRTUAL_ROOTS", false);
  637. NetAtoms [(int)NA._NET_DESKTOP_LAYOUT] = XInternAtom (DisplayHandle, "_NET_DESKTOP_LAYOUT", false);
  638. NetAtoms [(int)NA._NET_SHOWING_DESKTOP] = XInternAtom (DisplayHandle, "_NET_SHOWING_DESKTOP", false);
  639. NetAtoms [(int)NA._NET_CLOSE_WINDOW] = XInternAtom (DisplayHandle, "_NET_CLOSE_WINDOW", false);
  640. NetAtoms [(int)NA._NET_MOVERESIZE_WINDOW] = XInternAtom (DisplayHandle, "_NET_MOVERESIZE_WINDOW", false);
  641. NetAtoms [(int)NA._NET_WM_MOVERESIZE] = XInternAtom (DisplayHandle, "_NET_WM_MOVERESIZE", false);
  642. NetAtoms [(int)NA._NET_RESTACK_WINDOW] = XInternAtom (DisplayHandle, "_NET_RESTACK_WINDOW", false);
  643. NetAtoms [(int)NA._NET_REQUEST_FRAME_EXTENTS] = XInternAtom (DisplayHandle, "_NET_REQUEST_FRAME_EXTENTS", false);
  644. NetAtoms [(int)NA._NET_WM_NAME] = XInternAtom (DisplayHandle, "_NET_WM_NAME", false);
  645. NetAtoms [(int)NA._NET_WM_VISIBLE_NAME] = XInternAtom (DisplayHandle, "_NET_WM_VISIBLE_NAME", false);
  646. NetAtoms [(int)NA._NET_WM_ICON_NAME] = XInternAtom (DisplayHandle, "_NET_WM_ICON_NAME", false);
  647. NetAtoms [(int)NA._NET_WM_VISIBLE_ICON_NAME] = XInternAtom (DisplayHandle, "_NET_WM_VISIBLE_ICON_NAME", false);
  648. NetAtoms [(int)NA._NET_WM_DESKTOP] = XInternAtom (DisplayHandle, "_NET_WM_DESKTOP", false);
  649. NetAtoms [(int)NA._NET_WM_WINDOW_TYPE] = XInternAtom (DisplayHandle, "_NET_WM_WINDOW_TYPE", false);
  650. NetAtoms [(int)NA._NET_WM_STATE] = XInternAtom (DisplayHandle, "_NET_WM_STATE", false);
  651. NetAtoms [(int)NA._NET_WM_ALLOWED_ACTIONS] = XInternAtom (DisplayHandle, "_NET_WM_ALLOWED_ACTIONS", false);
  652. NetAtoms [(int)NA._NET_WM_STRUT] = XInternAtom (DisplayHandle, "_NET_WM_STRUT", false);
  653. NetAtoms [(int)NA._NET_WM_STRUT_PARTIAL] = XInternAtom (DisplayHandle, "_NET_WM_STRUT_PARTIAL", false);
  654. NetAtoms [(int)NA._NET_WM_ICON_GEOMETRY] = XInternAtom (DisplayHandle, "_NET_WM_ICON_GEOMETRY", false);
  655. NetAtoms [(int)NA._NET_WM_ICON] = XInternAtom (DisplayHandle, "_NET_WM_ICON", false);
  656. NetAtoms [(int)NA._NET_WM_PID] = XInternAtom (DisplayHandle, "_NET_WM_PID", false);
  657. NetAtoms [(int)NA._NET_WM_HANDLED_ICONS] = XInternAtom (DisplayHandle, "_NET_WM_HANDLED_ICONS", false);
  658. NetAtoms [(int)NA._NET_WM_USER_TIME] = XInternAtom (DisplayHandle, "_NET_WM_USER_TIME", false);
  659. NetAtoms [(int)NA._NET_FRAME_EXTENTS] = XInternAtom (DisplayHandle, "_NET_FRAME_EXTENTS", false);
  660. NetAtoms [(int)NA._NET_WM_PING] = XInternAtom (DisplayHandle, "_NET_WM_PING", false);
  661. NetAtoms [(int)NA._NET_WM_SYNC_REQUEST] = XInternAtom (DisplayHandle, "_NET_WM_SYNC_REQUEST", false);
  662. NetAtoms [(int)NA._NET_SYSTEM_TRAY_S] = XInternAtom (DisplayHandle, "_NET_SYSTEM_TRAY_S" + ScreenNo.ToString (), false);
  663. NetAtoms [(int)NA._NET_SYSTEM_TRAY_OPCODE] = XInternAtom (DisplayHandle, "_NET_SYSTEM_TRAY_OPCODE", false);
  664. NetAtoms [(int)NA._NET_SYSTEM_TRAY_ORIENTATION] = XInternAtom (DisplayHandle, "_NET_SYSTEM_TRAY_ORIENTATION", false);
  665. NetAtoms [(int)NA._NET_WM_STATE_MAXIMIZED_HORZ] = XInternAtom (DisplayHandle, "_NET_WM_STATE_MAXIMIZED_HORZ", false);
  666. NetAtoms [(int)NA._NET_WM_STATE_MAXIMIZED_VERT] = XInternAtom (DisplayHandle, "_NET_WM_STATE_MAXIMIZED_VERT", false);
  667. NetAtoms [(int)NA._NET_WM_STATE_HIDDEN] = XInternAtom (DisplayHandle, "_NET_WM_STATE_HIDDEN", false);
  668. NetAtoms [(int)NA._XEMBED] = XInternAtom (DisplayHandle, "_XEMBED", false);
  669. NetAtoms [(int)NA._XEMBED_INFO] = XInternAtom (DisplayHandle, "_XEMBED_INFO", false);
  670. NetAtoms [(int)NA._MOTIF_WM_HINTS] = XInternAtom (DisplayHandle, "_MOTIF_WM_HINTS", false);
  671. NetAtoms [(int)NA._NET_WM_STATE_NO_TASKBAR] = XInternAtom (DisplayHandle, "_NET_WM_STATE_NO_TASKBAR", false);
  672. NetAtoms [(int)NA._NET_WM_STATE_ABOVE] = XInternAtom (DisplayHandle, "_NET_WM_STATE_ABOVE", false);
  673. NetAtoms [(int)NA._NET_WM_STATE_MODAL] = XInternAtom (DisplayHandle, "_NET_WM_STATE_MODAL", false);
  674. NetAtoms [(int)NA._NET_WM_CONTEXT_HELP] = XInternAtom (DisplayHandle, "_NET_WM_CONTEXT_HELP", false);
  675. NetAtoms [(int)NA._NET_WM_WINDOW_OPACITY] = XInternAtom (DisplayHandle, "_NET_WM_WINDOW_OPACITY", false);
  676. // Clipboard support
  677. NetAtoms [(int)NA.CLIPBOARD] = XInternAtom (DisplayHandle, "CLIPBOARD", false);
  678. NetAtoms [(int)NA.DIB] = (int)Atom.XA_PIXMAP;
  679. NetAtoms [(int)NA.OEMTEXT] = XInternAtom (DisplayHandle, "COMPOUND_TEXT", false);
  680. NetAtoms [(int)NA.UNICODETEXT] = XInternAtom (DisplayHandle, "UTF8_STRING", false);
  681. NetAtoms [(int)NA.TARGETS] = XInternAtom (DisplayHandle, "TARGETS", false);
  682. // Special Atoms
  683. AsyncAtom = XInternAtom (DisplayHandle, "_SWF_AsyncAtom", false);
  684. PostAtom = XInternAtom (DisplayHandle, "_SWF_PostMessageAtom", false);
  685. HoverState.Atom = XInternAtom (DisplayHandle, "_SWF_HoverAtom", false);
  686. }
  687. private void GetSystrayManagerWindow ()
  688. {
  689. gdk_x11_grab_server ();
  690. SystrayMgrWindow = XGetSelectionOwner (DisplayHandle, NetAtoms [(int)NA._NET_SYSTEM_TRAY_S]);
  691. gdk_x11_ungrab_server ();
  692. gdk_display_flush (GdkDisplayHandle);
  693. }
  694. private void SendNetWMMessage (IntPtr window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2)
  695. {
  696. XEvent xev;
  697. xev = new XEvent ();
  698. xev.ClientMessageEvent.type = XEventName.ClientMessage;
  699. xev.ClientMessageEvent.send_event = true;
  700. xev.ClientMessageEvent.window = window;
  701. xev.ClientMessageEvent.message_type = message_type;
  702. xev.ClientMessageEvent.format = 32;
  703. xev.ClientMessageEvent.ptr1 = l0;
  704. xev.ClientMessageEvent.ptr2 = l1;
  705. xev.ClientMessageEvent.ptr3 = l2;
  706. XSendEvent (DisplayHandle, RootWindow, false, EventMask.SubstructureRedirectMask | EventMask.SubstructureNotifyMask, ref xev);
  707. }
  708. private void SendNetClientMessage (IntPtr window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2)
  709. {
  710. XEvent xev;
  711. xev = new XEvent ();
  712. xev.ClientMessageEvent.type = XEventName.ClientMessage;
  713. xev.ClientMessageEvent.send_event = true;
  714. xev.ClientMessageEvent.window = window;
  715. xev.ClientMessageEvent.message_type = message_type;
  716. xev.ClientMessageEvent.format = 32;
  717. xev.ClientMessageEvent.ptr1 = l0;
  718. xev.ClientMessageEvent.ptr2 = l1;
  719. xev.ClientMessageEvent.ptr3 = l2;
  720. XSendEvent (DisplayHandle, window, false, EventMask.NoEventMask, ref xev);
  721. }
  722. 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)
  723. {
  724. // Only MDI windows get caption_heights
  725. caption_height = 0;
  726. tool_caption_height = 19;
  727. if ((Style & (int) WindowStyles.WS_CHILD) != 0) {
  728. if ((Style & (int) WindowStyles.WS_BORDER) == 0) {
  729. border_style = FormBorderStyle.None;
  730. } else if ((ExStyle & (int) WindowStyles.WS_EX_CLIENTEDGE) != 0) {
  731. border_style = FormBorderStyle.Fixed3D;
  732. } else {
  733. border_style = FormBorderStyle.FixedSingle;
  734. }
  735. title_style = TitleStyle.None;
  736. } else {
  737. bool is_mdi = false;
  738. if ((ExStyle & (int) WindowStyles.WS_EX_MDICHILD) != 0) {
  739. caption_height = 26;
  740. is_mdi = true;
  741. }
  742. title_style = TitleStyle.None;
  743. if ((Style & (int)WindowStyles.WS_CAPTION) != 0) {
  744. if ((ExStyle & (int)WindowStyles.WS_EX_TOOLWINDOW) != 0) {
  745. title_style = TitleStyle.Tool;
  746. } else {
  747. title_style = TitleStyle.Normal;
  748. }
  749. }
  750. if (!is_mdi) {
  751. border_style = FormBorderStyle.None;
  752. if ((Style & (int)WindowStyles.WS_THICKFRAME) != 0) {
  753. if ((ExStyle & (int)WindowStyles.WS_EX_TOOLWINDOW) != 0) {
  754. border_style = FormBorderStyle.SizableToolWindow;
  755. } else {
  756. border_style = FormBorderStyle.Sizable;
  757. }
  758. } else {
  759. if ((ExStyle & (int)WindowStyles.WS_EX_CLIENTEDGE) != 0) {
  760. border_style = FormBorderStyle.Fixed3D;
  761. } else if ((ExStyle & (int)WindowStyles.WS_EX_DLGMODALFRAME) != 0) {
  762. border_style = FormBorderStyle.FixedDialog;
  763. } else if ((ExStyle & (int)WindowStyles.WS_EX_TOOLWINDOW) != 0) {
  764. border_style = FormBorderStyle.FixedToolWindow;
  765. } else if ((Style & (int)WindowStyles.WS_BORDER) != 0) {
  766. border_style = FormBorderStyle.Sizable;
  767. } else {
  768. border_style = FormBorderStyle.None;
  769. }
  770. }
  771. } else {
  772. if ((Style & (int) WindowStyles.WS_OVERLAPPEDWINDOW) != 0 ||
  773. (ExStyle & (int) WindowStyles.WS_EX_TOOLWINDOW) != 0) {
  774. border_style = (FormBorderStyle) 0xFFFF;
  775. } else {
  776. border_style = FormBorderStyle.None;
  777. }
  778. }
  779. }
  780. }
  781. private void SetHwndStyles (Hwnd hwnd, CreateParams cp)
  782. {
  783. DeriveStyles (hwnd.Handle, cp.Style, cp.ExStyle, out hwnd.border_style, out hwnd.title_style, out hwnd.caption_height, out hwnd.tool_caption_height);
  784. }
  785. private void SetWMStyles (Hwnd hwnd, CreateParams cp)
  786. {
  787. GdkWMDecoration decorations = GdkWMDecoration.GDK_DECOR_ALL;
  788. if ((cp.Style & (int)WindowStyles.WS_CAPTION) != 0) {
  789. decorations |= GdkWMDecoration.GDK_DECOR_TITLE | GdkWMDecoration.GDK_DECOR_MENU;
  790. }
  791. if ((cp.Style & ((int)WindowStyles.WS_THICKFRAME)) != 0) {
  792. decorations |= GdkWMDecoration.GDK_DECOR_BORDER | GdkWMDecoration.GDK_DECOR_RESIZEH;
  793. }
  794. if ((cp.Style & ((int)WindowStyles.WS_MINIMIZEBOX)) != 0) {
  795. decorations |= GdkWMDecoration.GDK_DECOR_MINIMIZE;
  796. }
  797. if ((cp.Style & ((int)WindowStyles.WS_MAXIMIZEBOX)) != 0) {
  798. decorations |= GdkWMDecoration.GDK_DECOR_MAXIMIZE;
  799. }
  800. // is this needed ? most window managers do not even honour any MotifFunctions...
  801. // if ((cp.Style & ((int)WindowStyles.WS_SYSMENU)) != 0) {
  802. // functions |= MotifFunctions.Close;
  803. // }
  804. if ((cp.ExStyle & ((int)WindowStyles.WS_EX_DLGMODALFRAME)) != 0) {
  805. decorations |= GdkWMDecoration.GDK_DECOR_BORDER;
  806. }
  807. if ((cp.Style & ((int)WindowStyles.WS_DLGFRAME)) != 0) {
  808. decorations |= GdkWMDecoration.GDK_DECOR_BORDER;
  809. }
  810. if ((cp.Style & ((int)WindowStyles.WS_BORDER)) != 0) {
  811. decorations |= GdkWMDecoration.GDK_DECOR_BORDER;
  812. }
  813. if ((cp.ExStyle & ((int)WindowStyles.WS_EX_TOOLWINDOW)) != 0) {
  814. decorations = 0;
  815. }
  816. gdk_window_set_decorations (gdk_window_foreign_new (hwnd.whole_window), (int)decorations);
  817. }
  818. private void SetIcon (Hwnd hwnd, Icon icon)
  819. {
  820. Bitmap bitmap;
  821. int size;
  822. uint[] data;
  823. int index;
  824. bitmap = icon.ToBitmap ();
  825. index = 0;
  826. size = bitmap.Width * bitmap.Height + 2;
  827. data = new uint [size];
  828. data [index++] = (uint)bitmap.Width;
  829. data [index++] = (uint)bitmap.Height;
  830. for (int y = 0; y < bitmap.Height; y++) {
  831. for (int x = 0; x < bitmap.Width; x++) {
  832. data [index++] = (uint)bitmap.GetPixel (x, y).ToArgb ();
  833. }
  834. }
  835. XChangeProperty (DisplayHandle, hwnd.whole_window, NetAtoms [(int)NA._NET_WM_ICON], Atom.XA_CARDINAL, 32, PropertyMode.Replace, data, size);
  836. }
  837. private IntPtr ImageToPixmap (Image image)
  838. {
  839. return IntPtr.Zero;
  840. }
  841. private void WakeupMain ()
  842. {
  843. wake.Send (new byte [] { 0xFF });
  844. }
  845. private void TranslatePropertyToClipboard (int property)
  846. {
  847. Atom actual_atom;
  848. int actual_format;
  849. int nitems;
  850. int bytes_after;
  851. IntPtr prop = IntPtr.Zero;
  852. Clipboard.Item = null;
  853. XGetWindowProperty (DisplayHandle, FosterParent, property, 0, 0x7fffffff, true, Atom.AnyPropertyType, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
  854. if (nitems > 0) {
  855. if (property == (int)Atom.XA_STRING) {
  856. Clipboard.Item = Marshal.PtrToStringAnsi (prop);
  857. } else if (property == (int)Atom.XA_BITMAP) {
  858. // FIXME - convert bitmap to image
  859. } else if (property == (int)Atom.XA_PIXMAP) {
  860. // FIXME - convert pixmap to image
  861. } else if (property == NetAtoms [(int)NA.OEMTEXT]) {
  862. Clipboard.Item = Marshal.PtrToStringAnsi (prop);
  863. } else if (property == NetAtoms [(int)NA.UNICODETEXT]) {
  864. Clipboard.Item = Marshal.PtrToStringAnsi (prop);
  865. }
  866. XFree (prop);
  867. }
  868. }
  869. private void AddExpose (XEvent xevent)
  870. {
  871. Hwnd hwnd;
  872. hwnd = Hwnd.GetObjectFromWindow (xevent.AnyEvent.window);
  873. // Don't waste time
  874. if (hwnd == null) {
  875. return;
  876. }
  877. if (xevent.AnyEvent.window == hwnd.client_window) {
  878. hwnd.AddInvalidArea (xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
  879. if (!hwnd.expose_pending) {
  880. MessageQueue.Enqueue (xevent);
  881. hwnd.expose_pending = true;
  882. }
  883. } else {
  884. if (!hwnd.nc_expose_pending) {
  885. MessageQueue.Enqueue (xevent);
  886. hwnd.nc_expose_pending = true;
  887. }
  888. }
  889. }
  890. private void InvalidateWholeWindow (IntPtr handle)
  891. {
  892. Hwnd hwnd;
  893. hwnd = Hwnd.ObjectFromHandle (handle);
  894. InvalidateWholeWindow (handle, new Rectangle (0, 0, hwnd.Width, hwnd.Height));
  895. }
  896. private void InvalidateWholeWindow (IntPtr handle, Rectangle rectangle)
  897. {
  898. Hwnd hwnd;
  899. XEvent xevent;
  900. hwnd = Hwnd.ObjectFromHandle (handle);
  901. xevent = new XEvent ();
  902. xevent.type = XEventName.Expose;
  903. xevent.ExposeEvent.display = DisplayHandle;
  904. xevent.ExposeEvent.window = hwnd.whole_window;
  905. xevent.ExposeEvent.x = rectangle.X;
  906. xevent.ExposeEvent.y = rectangle.Y;
  907. xevent.ExposeEvent.width = rectangle.Width;
  908. xevent.ExposeEvent.height = rectangle.Height;
  909. AddExpose (xevent);
  910. }
  911. private void WholeToScreen (IntPtr handle, ref int x, ref int y)
  912. {
  913. int dest_x_return;
  914. int dest_y_return;
  915. Hwnd hwnd;
  916. hwnd = Hwnd.ObjectFromHandle (handle);
  917. lock (XlibLock) {
  918. gdk_window_get_origin (gdk_window_lookup (hwnd.whole_window), out dest_x_return, out dest_y_return);
  919. }
  920. x = dest_x_return;
  921. y = dest_y_return;
  922. }
  923. private void AddConfigureNotify (XEvent xevent)
  924. {
  925. Hwnd hwnd;
  926. hwnd = Hwnd.GetObjectFromWindow (xevent.ConfigureEvent.window);
  927. // Don't waste time
  928. if (hwnd == null) {
  929. return;
  930. }
  931. if (xevent.ConfigureEvent.window == hwnd.whole_window) {
  932. if (!hwnd.reparented) {
  933. hwnd.x = xevent.ConfigureEvent.x;
  934. hwnd.y = xevent.ConfigureEvent.y;
  935. } else {
  936. int dummy_int;
  937. 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);
  938. }
  939. hwnd.width = xevent.ConfigureEvent.width;
  940. hwnd.height = xevent.ConfigureEvent.height;
  941. if (!hwnd.configure_pending) {
  942. MessageQueue.Enqueue (xevent);
  943. hwnd.configure_pending = true;
  944. }
  945. }
  946. // We drop configure events for Client windows
  947. }
  948. private void ShowCaret ()
  949. {
  950. if ((Caret.gc == IntPtr.Zero) || Caret.On) {
  951. return;
  952. }
  953. Caret.On = true;
  954. // gdk_gc_set_foreground
  955. // gdk_draw_line
  956. lock (XlibLock) {
  957. XDrawLine (DisplayHandle, Caret.Window, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
  958. }
  959. }
  960. private void HideCaret ()
  961. {
  962. if ((Caret.gc == IntPtr.Zero) || !Caret.On) {
  963. return;
  964. }
  965. Caret.On = false;
  966. // gdk_gc_set_foreground
  967. // gdk_draw_text_wc
  968. lock (XlibLock) {
  969. XDrawLine (DisplayHandle, Caret.Window, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
  970. }
  971. }
  972. private int NextTimeout (DateTime now)
  973. {
  974. int timeout = Int32.MaxValue;
  975. lock (TimerList) {
  976. foreach (Timer timer in TimerList) {
  977. int next = (int) (timer.Expires - now).TotalMilliseconds;
  978. if (next < 0) {
  979. return 0; // Have a timer that has already expired
  980. }
  981. if (next < timeout) {
  982. timeout = next;
  983. }
  984. }
  985. }
  986. if (timeout < Timer.Minimum) {
  987. timeout = Timer.Minimum;
  988. }
  989. return timeout;
  990. }
  991. private void CheckTimers (DateTime now)
  992. {
  993. lock (TimerList) {
  994. int count;
  995. count = TimerList.Count;
  996. if (count == 0) {
  997. return;
  998. }
  999. for (int i = 0; i < TimerList.Count; i++) {
  1000. Timer timer;
  1001. timer = (Timer) TimerList [i];
  1002. if (timer.Enabled && timer.Expires <= now) {
  1003. timer.Update (now);
  1004. timer.FireTick ();
  1005. }
  1006. }
  1007. }
  1008. }
  1009. private void UpdateMessageQueue ()
  1010. {
  1011. DateTime now;
  1012. int pending;
  1013. now = DateTime.Now;
  1014. lock (XlibLock) {
  1015. pending = XPending (DisplayHandle);
  1016. }
  1017. if (pending == 0) {
  1018. if (Idle != null) {
  1019. Idle (this, EventArgs.Empty);
  1020. }
  1021. lock (XlibLock) {
  1022. pending = XPending (DisplayHandle);
  1023. }
  1024. }
  1025. if (pending == 0) {
  1026. int timeout;
  1027. timeout = NextTimeout (now);
  1028. if (timeout > 0) {
  1029. #if __MonoCS__
  1030. Syscall.poll (pollfds, (uint) pollfds.Length, timeout);
  1031. // Clean out buffer, so we're not busy-looping on the same data
  1032. if (pollfds[1].revents != 0) {
  1033. wake_receive.Receive(network_buffer, 0, 1, SocketFlags.None);
  1034. }
  1035. #endif
  1036. lock (XlibLock) {
  1037. pending = XPending (DisplayHandle);
  1038. }
  1039. }
  1040. }
  1041. CheckTimers (now);
  1042. if (pending == 0) {
  1043. lock (XlibLock) {
  1044. pending = XPending (DisplayHandle);
  1045. }
  1046. }
  1047. while (pending > 0) {
  1048. XEvent xevent = new XEvent ();
  1049. lock (XlibLock) {
  1050. XNextEvent (DisplayHandle, ref xevent);
  1051. }
  1052. //Console.WriteLine("Got x event {0}", xevent);
  1053. switch (xevent.type) {
  1054. case XEventName.Expose:
  1055. AddExpose (xevent);
  1056. break;
  1057. case XEventName.SelectionClear: {
  1058. // Should we do something?
  1059. break;
  1060. }
  1061. case XEventName.SelectionRequest: {
  1062. if (Dnd.HandleSelectionRequestEvent (ref xevent))
  1063. break;
  1064. XEvent sel_event;
  1065. sel_event = new XEvent ();
  1066. sel_event.SelectionEvent.type = XEventName.SelectionNotify;
  1067. sel_event.SelectionEvent.send_event = true;
  1068. sel_event.SelectionEvent.display = DisplayHandle;
  1069. sel_event.SelectionEvent.selection = xevent.SelectionRequestEvent.selection;
  1070. sel_event.SelectionEvent.target = xevent.SelectionRequestEvent.target;
  1071. sel_event.SelectionEvent.requestor = xevent.SelectionRequestEvent.requestor;
  1072. sel_event.SelectionEvent.time = xevent.SelectionRequestEvent.time;
  1073. sel_event.SelectionEvent.property = 0;
  1074. // Seems that some apps support asking for supported types
  1075. if (xevent.SelectionEvent.target == NetAtoms [(int)NA.TARGETS]) {
  1076. uint[] atoms;
  1077. int atom_count;
  1078. atoms = new uint [5];
  1079. atom_count = 0;
  1080. if (Clipboard.Item is String) {
  1081. atoms [atom_count++] = (uint)Atom.XA_STRING;
  1082. atoms [atom_count++] = (uint)NetAtoms [(int)NA.OEMTEXT];
  1083. atoms [atom_count++] = (uint)NetAtoms [(int)NA.UNICODETEXT];
  1084. } else if (Clipboard.Item is Image) {
  1085. atoms [atom_count++] = (uint)Atom.XA_PIXMAP;
  1086. atoms [atom_count++] = (uint)Atom.XA_BITMAP;
  1087. } else {
  1088. // FIXME - handle other types
  1089. }
  1090. XChangeProperty (DisplayHandle, xevent.SelectionEvent.requestor, xevent.SelectionRequestEvent.property, xevent.SelectionRequestEvent.target, 32, PropertyMode.Replace, atoms, atom_count);
  1091. } else if (Clipboard.Item is string) {
  1092. IntPtr buffer;
  1093. int buflen;
  1094. buflen = 0;
  1095. if (xevent.SelectionRequestEvent.target == (int)Atom.XA_STRING) {
  1096. Byte[] bytes;
  1097. bytes = new ASCIIEncoding ().GetBytes ((string)Clipboard.Item);
  1098. buffer = Marshal.AllocHGlobal (bytes.Length);
  1099. buflen = bytes.Length;
  1100. for (int i = 0; i < buflen; i++) {
  1101. Marshal.WriteByte (buffer, i, bytes [i]);
  1102. }
  1103. } else if (xevent.SelectionRequestEvent.target == NetAtoms [(int)NA.OEMTEXT]) {
  1104. // FIXME - this should encode into ISO2022
  1105. buffer = Marshal.StringToHGlobalAnsi ((string)Clipboard.Item);
  1106. while (Marshal.ReadByte (buffer, buflen) != 0) {
  1107. buflen++;
  1108. }
  1109. } else if (xevent.SelectionRequestEvent.target == NetAtoms [(int)NA.UNICODETEXT]) {
  1110. buffer = Marshal.StringToHGlobalAnsi ((string)Clipboard.Item);
  1111. while (Marshal.ReadByte (buffer, buflen) != 0) {
  1112. buflen++;
  1113. }
  1114. } else {
  1115. buffer = IntPtr.Zero;
  1116. }
  1117. if (buffer != IntPtr.Zero) {
  1118. XChangeProperty (DisplayHandle, xevent.SelectionRequestEvent.requestor, xevent.SelectionRequestEvent.property, xevent.SelectionRequestEvent.target, 8, PropertyMode.Replace, buffer, buflen);
  1119. sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
  1120. Marshal.FreeHGlobal (buffer);
  1121. }
  1122. } else if (Clipboard.Item is Image) {
  1123. if (xevent.SelectionEvent.target == (int)Atom.XA_PIXMAP) {
  1124. // FIXME - convert image and store as property
  1125. } else if (xevent.SelectionEvent.target == (int)Atom.XA_PIXMAP) {
  1126. // FIXME - convert image and store as property
  1127. }
  1128. }
  1129. XSendEvent (DisplayHandle, xevent.SelectionRequestEvent.requestor, false, EventMask.NoEventMask, ref sel_event);
  1130. break;
  1131. }
  1132. case XEventName.SelectionNotify: {
  1133. if (Clipboard.Enumerating) {
  1134. Clipboard.Enumerating = false;
  1135. if (xevent.SelectionEvent.property != 0) {
  1136. XDeleteProperty (DisplayHandle, FosterParent, xevent.SelectionEvent.property);
  1137. if (!Clipboard.Formats.Contains (xevent.SelectionEvent.property)) {
  1138. Clipboard.Formats.Add (xevent.SelectionEvent.property);
  1139. #if DriverDebugExtra
  1140. Console.WriteLine("Got supported clipboard atom format: {0}", xevent.SelectionEvent.property);
  1141. #endif
  1142. }
  1143. }
  1144. } else if (Clipboard.Retrieving) {
  1145. Clipboard.Retrieving = false;
  1146. if (xevent.SelectionEvent.property != 0) {
  1147. TranslatePropertyToClipboard (xevent.SelectionEvent.property);
  1148. } else {
  1149. Clipboard.Item = null;
  1150. }
  1151. } else {
  1152. Dnd.HandleSelectionNotifyEvent (ref xevent);
  1153. }
  1154. break;
  1155. }
  1156. case XEventName.KeyPress:
  1157. case XEventName.KeyRelease:
  1158. case XEventName.ButtonPress:
  1159. case XEventName.ButtonRelease:
  1160. case XEventName.MotionNotify:
  1161. case XEventName.EnterNotify:
  1162. case XEventName.LeaveNotify:
  1163. case XEventName.CreateNotify:
  1164. case XEventName.DestroyNotify:
  1165. case XEventName.FocusIn:
  1166. case XEventName.FocusOut:
  1167. case XEventName.ClientMessage:
  1168. case XEventName.ReparentNotify:
  1169. MessageQueue.Enqueue (xevent);
  1170. break;
  1171. case XEventName.ConfigureNotify:
  1172. AddConfigureNotify (xevent);
  1173. break;
  1174. case XEventName.PropertyNotify:
  1175. if (xevent.PropertyEvent.atom == NetAtoms [(int)NA._NET_ACTIVE_WINDOW]) {
  1176. Atom actual_atom;
  1177. int actual_format;
  1178. int nitems;
  1179. int bytes_after;
  1180. IntPtr prop = IntPtr.Zero;
  1181. IntPtr prev_active;;
  1182. prev_active = ActiveWindow;
  1183. 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);
  1184. if ((nitems > 0) && (prop != IntPtr.Zero)) {
  1185. ActiveWindow = Hwnd.GetHandleFromWindow ((IntPtr)Marshal.ReadInt32 (prop));
  1186. XFree (prop);
  1187. if (prev_active != ActiveWindow) {
  1188. if (prev_active != IntPtr.Zero) {
  1189. PostMessage (prev_active, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_INACTIVE, IntPtr.Zero);
  1190. }
  1191. if (ActiveWindow != IntPtr.Zero) {
  1192. PostMessage (ActiveWindow, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_ACTIVE, IntPtr.Zero);
  1193. }
  1194. }
  1195. if (ModalWindows.Count == 0) {
  1196. break;
  1197. } else {
  1198. // Modality handling, if we are modal and the new active window is one
  1199. // of ours but not the modal one, switch back to the modal window
  1200. if (NativeWindow.FromHandle (ActiveWindow) != null) {
  1201. if (ActiveWindow != (IntPtr)ModalWindows.Peek ()) {
  1202. Activate ((IntPtr)ModalWindows.Peek ());
  1203. }
  1204. }
  1205. break;
  1206. }
  1207. }
  1208. }
  1209. break;
  1210. }
  1211. lock (XlibLock) {
  1212. pending = XPending (DisplayHandle);
  1213. }
  1214. }
  1215. }
  1216. private IntPtr GetMousewParam (int Delta)
  1217. {
  1218. int result = 0;
  1219. if ((MouseState & MouseButtons.Left) != 0) {
  1220. result |= (int)MsgButtons.MK_LBUTTON;
  1221. }
  1222. if ((MouseState & MouseButtons.Middle) != 0) {
  1223. result |= (int)MsgButtons.MK_MBUTTON;
  1224. }
  1225. if ((MouseState & MouseButtons.Right) != 0) {
  1226. result |= (int)MsgButtons.MK_RBUTTON;
  1227. }
  1228. Keys mods = ModifierKeys;
  1229. if ((mods & Keys.Control) != 0) {
  1230. result |= (int)MsgButtons.MK_CONTROL;
  1231. }
  1232. if ((mods & Keys.Shift) != 0) {
  1233. result |= (int)MsgButtons.MK_SHIFT;
  1234. }
  1235. result |= Delta << 16;
  1236. return (IntPtr)result;
  1237. }
  1238. private IntPtr XGetParent (IntPtr handle)
  1239. {
  1240. return gdk_x11_drawable_get_xid (gdk_window_get_parent (gdk_window_lookup (handle)));
  1241. }
  1242. private int HandleError (IntPtr display, ref XErrorEvent error_event)
  1243. {
  1244. if (ErrorExceptions) {
  1245. throw new XException (error_event.display, error_event.resourceid, error_event.serial, error_event.error_code, error_event.request_code, error_event.minor_code);
  1246. } else {
  1247. 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);
  1248. }
  1249. return 0;
  1250. }
  1251. private void DestroyChildWindow (Control c)
  1252. {
  1253. Hwnd hwnd;
  1254. int i;
  1255. Control[] controls;
  1256. if (c != null) {
  1257. controls = c.Controls.GetAllControls ();
  1258. for (i = 0; i < controls.Length; i++) {
  1259. if (controls [i].IsHandleCreated) {
  1260. hwnd = Hwnd.ObjectFromHandle (controls [i].Handle);
  1261. SendMessage (controls [i].Handle, Msg.WM_DESTROY, IntPtr.Zero, IntPtr.Zero);
  1262. hwnd.Dispose ();
  1263. }
  1264. DestroyChildWindow (controls [i]);
  1265. }
  1266. }
  1267. }
  1268. #endregion // Private Methods
  1269. #region Callbacks
  1270. private void MouseHover (object sender, EventArgs e)
  1271. {
  1272. if ((HoverState.X == MousePosition.X) && (HoverState.Y == MousePosition.Y)) {
  1273. XEvent xevent;
  1274. HoverState.Timer.Enabled = false;
  1275. if (HoverState.Window != IntPtr.Zero) {
  1276. xevent = new XEvent ();
  1277. xevent.type = XEventName.ClientMessage;
  1278. xevent.ClientMessageEvent.display = DisplayHandle;
  1279. xevent.ClientMessageEvent.window = (IntPtr)HoverState.Window;
  1280. xevent.ClientMessageEvent.message_type = (IntPtr)HoverState.Atom;
  1281. xevent.ClientMessageEvent.format = 32;
  1282. xevent.ClientMessageEvent.ptr1 = (IntPtr) (HoverState.Y << 16 | HoverState.X);
  1283. MessageQueue.EnqueueLocked (xevent);
  1284. WakeupMain ();
  1285. }
  1286. }
  1287. }
  1288. private void CaretCallback (object sender, EventArgs e)
  1289. {
  1290. if (Caret.Paused) {
  1291. return;
  1292. }
  1293. Caret.On = !Caret.On;
  1294. XDrawLine (DisplayHandle, Caret.Hwnd, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
  1295. }
  1296. #endregion // Callbacks
  1297. #region Public Properties
  1298. internal override int Caption {
  1299. get {
  1300. return 25;
  1301. }
  1302. }
  1303. internal override Size CursorSize {
  1304. get {
  1305. uint x;
  1306. uint y;
  1307. gdk_display_get_maximal_cursor_size (GdkDisplayHandle, out x, out y);
  1308. return new Size ((int)x, (int)y);
  1309. }
  1310. }
  1311. internal override bool DragFullWindows {
  1312. get {
  1313. return true;
  1314. }
  1315. }
  1316. internal override Size DragSize {
  1317. get {
  1318. return new Size (4, 4);
  1319. }
  1320. }
  1321. internal override Size FrameBorderSize {
  1322. get {
  1323. throw new NotImplementedException ();
  1324. }
  1325. }
  1326. internal override Size IconSize {
  1327. get {
  1328. IntPtr list;
  1329. XIconSize size;
  1330. int count;
  1331. if (XGetIconSizes (DisplayHandle, RootWindow, out list, out count) != 0) {
  1332. long current;
  1333. int largest;
  1334. current = (long)list;
  1335. largest = 0;
  1336. size = new XIconSize ();
  1337. for (int i = 0; i < count; i++) {
  1338. size = (XIconSize)Marshal.PtrToStructure ((IntPtr)current, size.GetType ());
  1339. current += Marshal.SizeOf (size);
  1340. // Look for our preferred size
  1341. if (size.min_width == 32) {
  1342. XFree (list);
  1343. return new Size (32, 32);
  1344. }
  1345. if (size.max_width == 32) {
  1346. XFree (list);
  1347. return new Size (32, 32);
  1348. }
  1349. if (size.min_width < 32 && size.max_width > 32) {
  1350. int x;
  1351. // check if we can fit one
  1352. x = size.min_width;
  1353. while (x < size.max_width) {
  1354. x += size.width_inc;
  1355. if (x == 32) {
  1356. XFree (list);
  1357. return new Size (32, 32);
  1358. }
  1359. }
  1360. }
  1361. if (largest < size.max_width) {
  1362. largest = size.max_width;
  1363. }
  1364. }
  1365. // We didn't find a match or we wouldn't be here
  1366. return new Size (largest, largest);
  1367. } else {
  1368. return new Size (32, 32);
  1369. }
  1370. }
  1371. }
  1372. internal override int KeyboardSpeed {
  1373. get {
  1374. //
  1375. // A lot harder: need to do:
  1376. // XkbQueryExtension(0x08051008, 0xbfffdf4c, 0xbfffdf50, 0xbfffdf54, 0xbfffdf58) = 1
  1377. // XkbAllocKeyboard(0x08051008, 0xbfffdf4c, 0xbfffdf50, 0xbfffdf54, 0xbfffdf58) = 0x080517a8
  1378. // XkbGetControls(0x08051008, 1, 0x080517a8, 0xbfffdf54, 0xbfffdf58) = 0
  1379. //
  1380. // And from that we can tell the repetition rate
  1381. //
  1382. // Notice, the values must map to:
  1383. // [0, 31] which maps to 2.5 to 30 repetitions per second.
  1384. //
  1385. return 0;
  1386. }
  1387. }
  1388. internal override int KeyboardDelay {
  1389. get {
  1390. //
  1391. // Return values must range from 0 to 4, 0 meaning 250ms,
  1392. // and 4 meaning 1000 ms.
  1393. //
  1394. return 1; // ie, 500 ms
  1395. }
  1396. }
  1397. internal override Size MaxWindowTrackSize {
  1398. get {
  1399. return new Size (WorkingArea.Width, WorkingArea.Height);
  1400. }
  1401. }
  1402. internal override Size MinimizedWindowSize {
  1403. get {
  1404. return new Size (1, 1);
  1405. }
  1406. }
  1407. internal override Size MinimizedWindowSpacingSize {
  1408. get {
  1409. return new Size (1, 1);
  1410. }
  1411. }
  1412. internal override Size MinimumWindowSize {
  1413. get {
  1414. return new Size (1, 1);
  1415. }
  1416. }
  1417. internal override Size MinWindowTrackSize {
  1418. get {
  1419. return new Size (1, 1);
  1420. }
  1421. }
  1422. internal override Keys ModifierKeys {
  1423. get {
  1424. return Keyboard.ModifierKeys;
  1425. }
  1426. }
  1427. internal override Size SmallIconSize {
  1428. get {
  1429. IntPtr list;
  1430. XIconSize size;
  1431. int count;
  1432. if (XGetIconSizes (DisplayHandle, RootWindow, out list, out count) != 0) {
  1433. long current;
  1434. int smallest;
  1435. current = (long)list;
  1436. smallest = 0;
  1437. size = new XIconSize ();
  1438. for (int i = 0; i < count; i++) {
  1439. size = (XIconSize)Marshal.PtrToStructure ((IntPtr)current, size.GetType ());
  1440. current += Marshal.SizeOf (size);
  1441. // Look for our preferred size
  1442. if (size.min_width == 16) {
  1443. XFree (list);
  1444. return new Size (16, 16);
  1445. }
  1446. if (size.max_width == 16) {
  1447. XFree (list);
  1448. return new Size (16, 16);
  1449. }
  1450. if (size.min_width < 16 && size.max_width > 16) {
  1451. int x;
  1452. // check if we can fit one
  1453. x = size.min_width;
  1454. while (x < size.max_width) {
  1455. x += size.width_inc;
  1456. if (x == 16) {
  1457. XFree (list);
  1458. return new Size (16, 16);
  1459. }
  1460. }
  1461. }
  1462. if (smallest == 0 || smallest > size.min_width) {
  1463. smallest = size.min_width;
  1464. }
  1465. }
  1466. // We didn't find a match or we wouldn't be here
  1467. return new Size (smallest, smallest);
  1468. } else {
  1469. return new Size (16, 16);
  1470. }
  1471. }
  1472. }
  1473. internal override int MouseButtonCount {
  1474. get {
  1475. return 3;
  1476. }
  1477. }
  1478. internal override bool MouseButtonsSwapped {
  1479. get {
  1480. return false; // FIXME - how to detect?
  1481. }
  1482. }
  1483. internal override bool MouseWheelPresent {
  1484. get {
  1485. return true; // FIXME - how to detect?
  1486. }
  1487. }
  1488. internal override Rectangle VirtualScreen {
  1489. get {
  1490. return WorkingArea;
  1491. }
  1492. }
  1493. internal override Rectangle WorkingArea {
  1494. get {
  1495. Atom actual_atom;
  1496. int actual_format;
  1497. int nitems;
  1498. int bytes_after;
  1499. IntPtr prop = IntPtr.Zero;
  1500. int width;
  1501. int height;
  1502. 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);
  1503. if ((nitems == 2) && (prop != IntPtr.Zero)) {
  1504. width = Marshal.ReadInt32 (prop, 0);
  1505. height = Marshal.ReadInt32 (prop, 4);
  1506. XFree (prop);
  1507. return new Rectangle (0, 0, width, height);
  1508. } else {
  1509. XWindowAttributes attributes=new XWindowAttributes ();
  1510. lock (XlibLock) {
  1511. XGetWindowAttributes (DisplayHandle, XRootWindow (DisplayHandle, ScreenNo), ref attributes);
  1512. }
  1513. return new Rectangle (0, 0, attributes.width, attributes.height);
  1514. }
  1515. }
  1516. }
  1517. #endregion // Public properties
  1518. #region Public Static Methods
  1519. internal override IntPtr InitializeDriver ()
  1520. {
  1521. lock (this) {
  1522. if (GdkDisplayHandle == IntPtr.Zero) {
  1523. SetDisplay (gdk_x11_display_get_xdisplay (gdk_display_get_default ()));
  1524. }
  1525. }
  1526. return IntPtr.Zero;
  1527. }
  1528. internal override void ShutdownDriver (IntPtr token)
  1529. {
  1530. lock (this) {
  1531. if (GdkDisplayHandle != IntPtr.Zero) {
  1532. gdk_display_close (GdkDisplayHandle);
  1533. DisplayHandle = IntPtr.Zero;
  1534. GdkDisplayHandle = IntPtr.Zero;
  1535. }
  1536. }
  1537. }
  1538. internal override void EnableThemes ()
  1539. {
  1540. ThemesEnabled = true;
  1541. }
  1542. internal override void Activate (IntPtr handle)
  1543. {
  1544. Hwnd hwnd;
  1545. hwnd = Hwnd.ObjectFromHandle (handle);
  1546. if (hwnd != null) lock (XlibLock) {
  1547. SendNetWMMessage (hwnd.whole_window, (IntPtr)NetAtoms [(int)NA._NET_ACTIVE_WINDOW], IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
  1548. //XRaiseWindow(DisplayHandle, handle);
  1549. }
  1550. return;
  1551. }
  1552. internal override void AudibleAlert ()
  1553. {
  1554. gdk_display_beep (gdk_x11_lookup_xdisplay (DisplayHandle));
  1555. return;
  1556. }
  1557. internal override void CaretVisible (IntPtr handle, bool visible)
  1558. {
  1559. // Visible is cumulative; two hides require two shows before the caret is visible again
  1560. if (Caret.Hwnd == handle) {
  1561. if (visible) {
  1562. if (Caret.Visible < 1) {
  1563. Caret.Visible++;
  1564. Caret.On = false;
  1565. if (Caret.Visible == 1) {
  1566. ShowCaret ();
  1567. Caret.Timer.Start ();
  1568. }
  1569. }
  1570. } else {
  1571. Caret.Visible--;
  1572. if (Caret.Visible == 0) {
  1573. Caret.Timer.Stop ();
  1574. HideCaret ();
  1575. }
  1576. }
  1577. }
  1578. }
  1579. internal override bool CalculateWindowRect (IntPtr handle, ref Rectangle ClientRect, int Style, int ExStyle, Menu menu, out Rectangle WindowRect)
  1580. {
  1581. FormBorderStyle border_style;
  1582. TitleStyle title_style;
  1583. int caption_height;
  1584. int tool_caption_height;
  1585. DeriveStyles (handle, Style, ExStyle, out border_style, out title_style,
  1586. out caption_height, out tool_caption_height);
  1587. WindowRect = Hwnd.GetWindowRectangle (border_style, menu, title_style,
  1588. caption_height, tool_caption_height,
  1589. ClientRect);
  1590. return true;
  1591. }
  1592. internal override void ClientToScreen (IntPtr handle, ref int x, ref int y)
  1593. {
  1594. int dest_x_return;
  1595. int dest_y_return;
  1596. IntPtr child;
  1597. Hwnd hwnd;
  1598. hwnd = Hwnd.ObjectFromHandle (handle);
  1599. lock (XlibLock) {
  1600. XTranslateCoordinates (DisplayHandle, hwnd.client_window, RootWindow, x, y, out dest_x_return, out dest_y_return, out child);
  1601. }
  1602. x = dest_x_return;
  1603. y = dest_y_return;
  1604. }
  1605. internal override int[] ClipboardAvailableFormats (IntPtr handle)
  1606. {
  1607. DataFormats.Format f;
  1608. int[] result;
  1609. f = DataFormats.Format.List;
  1610. if (XGetSelectionOwner (DisplayHandle, NetAtoms [(int)NA.CLIPBOARD]) == IntPtr.Zero) {
  1611. return null;
  1612. }
  1613. Clipboard.Formats = new ArrayList ();
  1614. while (f != null) {
  1615. XConvertSelection (DisplayHandle, NetAtoms [(int)NA.CLIPBOARD], f.Id, f.Id, FosterParent, IntPtr.Zero);
  1616. Clipboard.Enumerating = true;
  1617. while (Clipboard.Enumerating) {
  1618. UpdateMessageQueue ();
  1619. }
  1620. f = f.Next;
  1621. }
  1622. result = new int [Clipboard.Formats.Count];
  1623. for (int i = 0; i < Clipboard.Formats.Count; i++) {
  1624. result [i] = (int)Clipboard.Formats [i];
  1625. }
  1626. Clipboard.Formats = null;
  1627. return result;
  1628. }
  1629. internal override void ClipboardClose (IntPtr handle)
  1630. {
  1631. if (handle != ClipMagic) {
  1632. throw new ArgumentException ("handle is not a valid clipboard handle");
  1633. }
  1634. return;
  1635. }
  1636. internal override int ClipboardGetID (IntPtr handle, string format)
  1637. {
  1638. if (handle != ClipMagic) {
  1639. throw new ArgumentException ("handle is not a valid clipboard handle");
  1640. }
  1641. if (format == "Text") return (int)Atom.XA_STRING;
  1642. else if (format == "Bitmap") return (int)Atom.XA_BITMAP;
  1643. //else if (format == "MetaFilePict" ) return 3;
  1644. //else if (format == "SymbolicLink" ) return 4;
  1645. //else if (format == "DataInterchangeFormat" ) return 5;
  1646. //else if (format == "Tiff" ) return 6;
  1647. else if (format == "OEMText") return XInternAtom (DisplayHandle, "COMPOUND_TEXT", false);
  1648. else if (format == "DeviceIndependentBitmap") return (int)Atom.XA_PIXMAP;
  1649. else if (format == "Palette") return (int)Atom.XA_COLORMAP; // Useless
  1650. //else if (format == "PenData" ) return 10;
  1651. //else if (format == "RiffAudio" ) return 11;
  1652. //else if (format == "WaveAudio" ) return 12;
  1653. else if (format == "UnicodeText") return XInternAtom (DisplayHandle, "UTF8_STRING", false);
  1654. //else if (format == "EnhancedMetafile" ) return 14;
  1655. //else if (format == "FileDrop" ) return 15;
  1656. //else if (format == "Locale" ) return 16;
  1657. return XInternAtom (DisplayHandle, format, false);
  1658. }
  1659. internal override IntPtr ClipboardOpen ()
  1660. {
  1661. return ClipMagic;
  1662. }
  1663. internal override object ClipboardRetrieve (IntPtr handle, int type, XplatUI.ClipboardToObject converter)
  1664. {
  1665. XConvertSelection (DisplayHandle, NetAtoms [(int)NA.CLIPBOARD], type, type, FosterParent, IntPtr.Zero);
  1666. Clipboard.Retrieving = true;
  1667. while (Clipboard.Retrieving) {
  1668. UpdateMessageQueue ();
  1669. }
  1670. return Clipboard.Item;
  1671. }
  1672. internal override void ClipboardStore (IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter)
  1673. {
  1674. Clipboard.Item = obj;
  1675. Clipboard.Type = type;
  1676. Clipboard.Converter = converter;
  1677. if (obj != null) {
  1678. XSetSelectionOwner (DisplayHandle, NetAtoms [(int)NA.CLIPBOARD], FosterParent, IntPtr.Zero);
  1679. } else {
  1680. // Clearing the selection
  1681. XSetSelectionOwner (DisplayHandle, NetAtoms [(int)NA.CLIPBOARD], IntPtr.Zero, IntPtr.Zero);
  1682. }
  1683. }
  1684. internal override void CreateCaret (IntPtr handle, int width, int height)
  1685. {
  1686. XGCValues gc_values;
  1687. Hwnd hwnd;
  1688. hwnd = Hwnd.ObjectFromHandle (handle);
  1689. if (Caret.Hwnd != IntPtr.Zero) {
  1690. DestroyCaret (Caret.Hwnd);
  1691. }
  1692. Caret.Hwnd = handle;
  1693. Caret.Window = hwnd.client_window;
  1694. Caret.Width = width;
  1695. Caret.Height = height;
  1696. Caret.Visible = 0;
  1697. Caret.On = false;
  1698. gc_values = new XGCValues ();
  1699. gc_values.line_width = width;
  1700. Caret.gc = XCreateGC (DisplayHandle, Caret.Window, GCFunction.GCLineWidth, ref gc_values);
  1701. if (Caret.gc == IntPtr.Zero) {
  1702. Caret.Hwnd = IntPtr.Zero;
  1703. return;
  1704. }
  1705. XSetFunction (DisplayHandle, Caret.gc, GXFunction.GXinvert);
  1706. }
  1707. internal override IntPtr CreateWindow (CreateParams cp)
  1708. {
  1709. GdkWindowAttr gdk_window_attributes;
  1710. GdkWindowAttributesType attributes_mask = 0;
  1711. Hwnd hwnd;
  1712. int X;
  1713. int Y;
  1714. int Width;
  1715. int Height;
  1716. IntPtr GdkParentHandle;
  1717. IntPtr GdkWholeWindow;
  1718. IntPtr GdkClientWindow;
  1719. Rectangle ClientRect;
  1720. GdkWindowType gdk_window_type;
  1721. hwnd = new Hwnd ();
  1722. gdk_window_attributes = new GdkWindowAttr ();
  1723. X = cp.X;
  1724. Y = cp.Y;
  1725. Width = cp.Width;
  1726. Height = cp.Height;
  1727. if (Width < 1) Width = 1;
  1728. if (Height < 1) Height = 1;
  1729. gdk_window_type = GdkWindowType.GDK_WINDOW_CHILD;
  1730. if (cp.Parent != IntPtr.Zero) {
  1731. GdkParentHandle = gdk_window_lookup (Hwnd.ObjectFromHandle (cp.Parent).client_window);
  1732. } else {
  1733. if ((cp.Style & (int)WindowStyles.WS_CHILD) != 0) {
  1734. // We need to use our foster parent window until this poor child gets it's parent assigned
  1735. GdkParentHandle = GdkFosterParent;
  1736. } else if ((cp.Style & (int)WindowStyles.WS_POPUP) != 0) {
  1737. GdkParentHandle = GdkRootWindow;
  1738. } else {
  1739. // Default position on screen, if window manager doesn't place us somewhere else
  1740. if (X < 1) X = 50;
  1741. if (Y < 1) Y = 50;
  1742. GdkParentHandle = GdkRootWindow;
  1743. }
  1744. }
  1745. // ValueMask = SetWindowValuemask.BitGravity | SetWindowValuemask.WinGravity;
  1746. // Attributes.bit_gravity = Gravity.NorthWestGravity;
  1747. // Attributes.win_gravity = Gravity.NorthWestGravity;
  1748. // FIXME: does gdk need that ?
  1749. // Save what's under the toolwindow
  1750. if ((cp.ExStyle & (int)WindowStyles.WS_EX_TOOLWINDOW) != 0) {
  1751. // Attributes.save_under = true;
  1752. // ValueMask |= SetWindowValuemask.SaveUnder;
  1753. }
  1754. // If we're a popup without caption we override the WM
  1755. if ((cp.Style & ((int)WindowStyles.WS_POPUP)) != 0) {
  1756. if ((cp.Style & (int)WindowStyles.WS_CAPTION) == 0) {
  1757. gdk_window_attributes.override_redirect = true;
  1758. attributes_mask |= GdkWindowAttributesType.GDK_WA_NOREDIR;
  1759. }
  1760. }
  1761. hwnd.x = X;
  1762. hwnd.y = Y;
  1763. hwnd.width = Width;
  1764. hwnd.height = Height;
  1765. hwnd.parent = Hwnd.ObjectFromHandle (cp.Parent);
  1766. if ((cp.Style & ((int)WindowStyles.WS_DISABLED)) != 0) {
  1767. hwnd.enabled = false;
  1768. }
  1769. ClientRect = hwnd.ClientRect;
  1770. GdkClientWindow = IntPtr.Zero;
  1771. gdk_window_attributes.x = X;
  1772. gdk_window_attributes.y = Y;
  1773. gdk_window_attributes.width = Width;
  1774. gdk_window_attributes.height = Height;
  1775. gdk_window_attributes.window_type = gdk_window_type;
  1776. attributes_mask |= GdkWindowAttributesType.GDK_WA_X | GdkWindowAttributesType.GDK_WA_Y;
  1777. gdk_window_attributes.wclass = GdkWindowClass.GDK_INPUT_OUTPUT;
  1778. lock (XlibLock) {
  1779. GdkWholeWindow = gdk_window_new (GdkParentHandle, ref gdk_window_attributes, (int)attributes_mask);
  1780. if (GdkWholeWindow != IntPtr.Zero) {
  1781. attributes_mask &= ~GdkWindowAttributesType.GDK_WA_NOREDIR;
  1782. if (GdkCustomVisual != IntPtr.Zero && GdkCustomColormap != IntPtr.Zero) {
  1783. attributes_mask |= GdkWindowAttributesType.GDK_WA_COLORMAP | GdkWindowAttributesType.GDK_WA_VISUAL;
  1784. gdk_window_attributes.colormap = GdkCustomColormap;
  1785. gdk_window_attributes.visual = GdkCustomVisual;
  1786. }
  1787. gdk_window_attributes.x = ClientRect.X;
  1788. gdk_window_attributes.y = ClientRect.Y;
  1789. gdk_window_attributes.width = ClientRect.Width;
  1790. gdk_window_attributes.height = ClientRect.Height;
  1791. GdkClientWindow = gdk_window_new (GdkWholeWindow, ref gdk_window_attributes, (int)attributes_mask);
  1792. }
  1793. }
  1794. if ((GdkWholeWindow == IntPtr.Zero) || (GdkClientWindow == IntPtr.Zero)) {
  1795. throw new Exception ("Could not create X11 Gdk windows");
  1796. }
  1797. hwnd.WholeWindow = gdk_x11_drawable_get_xid (GdkWholeWindow);
  1798. hwnd.ClientWindow = gdk_x11_drawable_get_xid (GdkClientWindow);
  1799. #if DriverDebug
  1800. Console.WriteLine("Created window {0:X} / {1:X} parent {2:X}", ClientWindow.ToInt32(), WholeWindow.ToInt32(), hwnd.parent != null ? hwnd.parent.Handle.ToInt32() : 0);
  1801. #endif
  1802. lock (XlibLock) {
  1803. gdk_window_set_events (GdkWholeWindow, (int)GdkSelectInputMask);
  1804. gdk_window_set_events (GdkClientWindow, (int)GdkSelectInputMask);
  1805. if ((cp.Style & (int)WindowStyles.WS_VISIBLE) != 0) {
  1806. gdk_window_show (GdkWholeWindow);
  1807. gdk_window_show (GdkClientWindow);
  1808. hwnd.visible = true;
  1809. }
  1810. }
  1811. SetWMStyles (hwnd, cp);
  1812. if ((cp.Style & (int)WindowStyles.WS_MINIMIZE) != 0) {
  1813. SetWindowState (hwnd.Handle, FormWindowState.Minimized);
  1814. } else if ((cp.Style & (int)WindowStyles.WS_MAXIMIZE) != 0) {
  1815. SetWindowState (hwnd.Handle, FormWindowState.Maximized);
  1816. }
  1817. // for now make all windows dnd enabled
  1818. Dnd.SetAllowDrop (hwnd, true);
  1819. // Set caption/window title
  1820. Text (hwnd.Handle, cp.Caption);
  1821. return hwnd.Handle;
  1822. }
  1823. internal override IntPtr CreateWindow (IntPtr Parent, int X, int Y, int Width, int Height)
  1824. {
  1825. CreateParams create_params = new CreateParams ();
  1826. create_params.Caption = "";
  1827. create_params.X = X;
  1828. create_params.Y = Y;
  1829. create_params.Width = Width;
  1830. create_params.Height = Height;
  1831. create_params.ClassName = XplatUI.DefaultClassName;
  1832. create_params.ClassStyle = 0;
  1833. create_params.ExStyle = 0;
  1834. create_params.Parent = IntPtr.Zero;
  1835. create_params.Param = 0;
  1836. return CreateWindow (create_params);
  1837. }
  1838. internal override IntPtr DefineCursor (Bitmap bitmap, Bitmap mask, Color cursor_pixel, Color mask_pixel, int xHotSpot, int yHotSpot)
  1839. {
  1840. IntPtr cursor;
  1841. Bitmap cursor_bitmap;
  1842. Bitmap cursor_mask;
  1843. Byte[] cursor_bits;
  1844. Byte[] mask_bits;
  1845. Color c_pixel;
  1846. Color m_pixel;
  1847. int width;
  1848. int height;
  1849. IntPtr cursor_pixmap;
  1850. IntPtr mask_pixmap;
  1851. XColor fg;
  1852. XColor bg;
  1853. bool and;
  1854. bool xor;
  1855. Size cursor_size = CursorSize;
  1856. width = cursor_size.Width;
  1857. height = cursor_size.Height;
  1858. // Win32 only allows creation cursors of a certain size
  1859. if ((bitmap.Width != width) || (bitmap.Width != height)) {
  1860. cursor_bitmap = new Bitmap (bitmap, new Size (width, height));
  1861. cursor_mask = new Bitmap (mask, new Size (width, height));
  1862. } else {
  1863. cursor_bitmap = bitmap;
  1864. cursor_mask = mask;
  1865. }
  1866. width = cursor_bitmap.Width;
  1867. height = cursor_bitmap.Height;
  1868. cursor_bits = new Byte [(width / 8) * height];
  1869. mask_bits = new Byte [(width / 8) * height];
  1870. for (int y = 0; y < height; y++) {
  1871. for (int x = 0; x < width; x++) {
  1872. c_pixel = cursor_bitmap.GetPixel (x, y);
  1873. m_pixel = cursor_mask.GetPixel (x, y);
  1874. and = c_pixel == cursor_pixel;
  1875. xor = m_pixel == mask_pixel;
  1876. if (!and && !xor) {
  1877. // Black
  1878. // cursor_bits[y * width / 8 + x / 8] &= (byte)~((1 << (x % 8))); // The bit already is 0
  1879. mask_bits [y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
  1880. } else if (and && !xor) {
  1881. // White
  1882. cursor_bits [y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
  1883. mask_bits [y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
  1884. #if notneeded
  1885. } else if (and && !xor) {
  1886. // Screen
  1887. } else if (and && xor) {
  1888. // Inverse Screen
  1889. // X11 doesn't know the 'reverse screen' concept, so we'll treat them the same
  1890. // we want both to be 0 so nothing to be done
  1891. //cursor_bits[y * width / 8 + x / 8] &= (byte)~((1 << (x % 8)));
  1892. //mask_bits[y * width / 8 + x / 8] |= (byte)(01 << (x % 8));
  1893. #endif
  1894. }
  1895. }
  1896. }
  1897. cursor_pixmap = XCreatePixmapFromBitmapData (DisplayHandle, RootWindow, cursor_bits, width, height, (IntPtr)1, (IntPtr)0, 1);
  1898. mask_pixmap = XCreatePixmapFromBitmapData (DisplayHandle, RootWindow, mask_bits, width, height, (IntPtr)1, (IntPtr)0, 1);
  1899. fg = new XColor ();
  1900. bg = new XColor ();
  1901. fg.pixel = XWhitePixel (DisplayHandle, ScreenNo);
  1902. fg.red = (ushort)65535;
  1903. fg.green = (ushort)65535;
  1904. fg.blue = (ushort)65535;
  1905. bg.pixel = XBlackPixel (DisplayHandle, ScreenNo);
  1906. cursor = XCreatePixmapCursor (DisplayHandle, cursor_pixmap, mask_pixmap, ref fg, ref bg, xHotSpot, yHotSpot);
  1907. XFreePixmap (DisplayHandle, cursor_pixmap);
  1908. XFreePixmap (DisplayHandle, mask_pixmap);
  1909. return cursor;
  1910. }
  1911. internal override IntPtr DefineStdCursor (StdCursor id)
  1912. {
  1913. CursorFontShape shape;
  1914. IntPtr cursor;
  1915. // FIXME - define missing shapes
  1916. switch (id) {
  1917. case StdCursor.AppStarting: {
  1918. shape = CursorFontShape.XC_watch;
  1919. break;
  1920. }
  1921. case StdCursor.Arrow: {
  1922. return IntPtr.Zero;
  1923. }
  1924. case StdCursor.Cross: {
  1925. shape = CursorFontShape.XC_crosshair;
  1926. break;
  1927. }
  1928. case StdCursor.Default: {
  1929. return IntPtr.Zero;
  1930. }
  1931. case StdCursor.Hand: {
  1932. shape = CursorFontShape.XC_hand1;
  1933. break;
  1934. }
  1935. case StdCursor.Help: {
  1936. shape = CursorFontShape.XC_question_arrow;
  1937. break;
  1938. }
  1939. case StdCursor.HSplit: {
  1940. shape = CursorFontShape.XC_sb_v_double_arrow;
  1941. break;
  1942. }
  1943. case StdCursor.IBeam: {
  1944. shape = CursorFontShape.XC_xterm;
  1945. break;
  1946. }
  1947. case StdCursor.No: {
  1948. shape = CursorFontShape.XC_circle;
  1949. break;
  1950. }
  1951. case StdCursor.NoMove2D: {
  1952. shape = CursorFontShape.XC_fleur;
  1953. break;
  1954. }
  1955. case StdCursor.NoMoveHoriz: {
  1956. shape = CursorFontShape.XC_fleur;
  1957. break;
  1958. }
  1959. case StdCursor.NoMoveVert: {
  1960. shape = CursorFontShape.XC_fleur;
  1961. break;
  1962. }
  1963. case StdCursor.PanEast: {
  1964. shape = CursorFontShape.XC_fleur;
  1965. break;
  1966. }
  1967. case StdCursor.PanNE: {
  1968. shape = CursorFontShape.XC_fleur;
  1969. break;
  1970. }
  1971. case StdCursor.PanNorth: {
  1972. shape = CursorFontShape.XC_fleur;
  1973. break;
  1974. }
  1975. case StdCursor.PanNW: {
  1976. shape = CursorFontShape.XC_fleur;
  1977. break;
  1978. }
  1979. case StdCursor.PanSE: {
  1980. shape = CursorFontShape.XC_fleur;
  1981. break;
  1982. }
  1983. case StdCursor.PanSouth: {
  1984. shape = CursorFontShape.XC_fleur;
  1985. break;
  1986. }
  1987. case StdCursor.PanSW: {
  1988. shape = CursorFontShape.XC_fleur;
  1989. break;
  1990. }
  1991. case StdCursor.PanWest: {
  1992. shape = CursorFontShape.XC_sizing;
  1993. break;
  1994. }
  1995. case StdCursor.SizeAll: {
  1996. shape = CursorFontShape.XC_fleur;
  1997. break;
  1998. }
  1999. case StdCursor.SizeNESW: {
  2000. shape = CursorFontShape.XC_top_right_corner;
  2001. break;
  2002. }
  2003. case StdCursor.SizeNS: {
  2004. shape = CursorFontShape.XC_sb_v_double_arrow;
  2005. break;
  2006. }
  2007. case StdCursor.SizeNWSE: {
  2008. shape = CursorFontShape.XC_top_left_corner;
  2009. break;
  2010. }
  2011. case StdCursor.SizeWE: {
  2012. shape = CursorFontShape.XC_sb_h_double_arrow;
  2013. break;
  2014. }
  2015. case StdCursor.UpArrow: {
  2016. shape = CursorFontShape.XC_center_ptr;
  2017. break;
  2018. }
  2019. case StdCursor.VSplit: {
  2020. shape = CursorFontShape.XC_sb_h_double_arrow;
  2021. break;
  2022. }
  2023. case StdCursor.WaitCursor: {
  2024. shape = CursorFontShape.XC_watch;
  2025. break;
  2026. }
  2027. default: {
  2028. return IntPtr.Zero;
  2029. }
  2030. }
  2031. lock (XlibLock) {
  2032. cursor = XCreateFontCursor (DisplayHandle, shape);
  2033. }
  2034. return cursor;
  2035. }
  2036. internal override IntPtr DefWndProc (ref Message msg)
  2037. {
  2038. return IntPtr.Zero;
  2039. }
  2040. internal override void DestroyCaret (IntPtr handle)
  2041. {
  2042. if (Caret.Hwnd == handle) {
  2043. if (Caret.Visible == 1) {
  2044. Caret.Timer.Stop ();
  2045. HideCaret ();
  2046. }
  2047. if (Caret.gc != IntPtr.Zero) {
  2048. XFreeGC (DisplayHandle, Caret.gc);
  2049. Caret.gc = IntPtr.Zero;
  2050. }
  2051. Caret.Hwnd = IntPtr.Zero;
  2052. Caret.Visible = 0;
  2053. Caret.On = false;
  2054. }
  2055. }
  2056. internal override void DestroyCursor (IntPtr cursor)
  2057. {
  2058. lock (XlibLock) {
  2059. XFreeCursor (DisplayHandle, cursor);
  2060. }
  2061. }
  2062. internal override void DestroyWindow (IntPtr handle)
  2063. {
  2064. Hwnd hwnd;
  2065. hwnd = Hwnd.ObjectFromHandle (handle);
  2066. if (hwnd == null) {
  2067. #if DriverDebug
  2068. Console.WriteLine("window {0:X} already destroyed", handle.ToInt32());
  2069. #endif
  2070. return;
  2071. }
  2072. #if DriverDebug
  2073. Console.WriteLine("Destroying window {0:X}", handle.ToInt32());
  2074. #endif
  2075. // Make sure if the caret is in the window, that we destroy the caret, too
  2076. if (Caret.Hwnd == hwnd.client_window) {
  2077. DestroyCaret (handle);
  2078. }
  2079. // Mark our children as gone as well
  2080. DestroyChildWindow (Control.ControlNativeWindow.ControlFromHandle (handle));
  2081. // Send destroy message
  2082. SendMessage (handle, Msg.WM_DESTROY, IntPtr.Zero, IntPtr.Zero);
  2083. lock (XlibLock) {
  2084. if (hwnd.client_window != IntPtr.Zero) {
  2085. gdk_window_destroy (gdk_window_lookup (hwnd.client_window));
  2086. }
  2087. if ((hwnd.whole_window != IntPtr.Zero) && (hwnd.whole_window != hwnd.client_window)) {
  2088. gdk_window_destroy (gdk_window_lookup (hwnd.whole_window));
  2089. }
  2090. }
  2091. hwnd.Dispose ();
  2092. }
  2093. internal override IntPtr DispatchMessage (ref MSG msg)
  2094. {
  2095. return NativeWindow.WndProc (msg.hwnd, msg.message, msg.wParam, msg.lParam);
  2096. }
  2097. internal override void DrawReversibleRectangle (IntPtr handle, Rectangle rect, int line_width)
  2098. {
  2099. Hwnd hwnd;
  2100. XGCValues gc_values;
  2101. IntPtr gc;
  2102. hwnd = Hwnd.ObjectFromHandle (handle);
  2103. gc_values = new XGCValues ();
  2104. gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
  2105. gc_values.line_width = line_width;
  2106. gc_values.foreground = XBlackPixel (DisplayHandle, ScreenNo);
  2107. // This logic will give us true rubber bands: (libsx, SANE_XOR)
  2108. //mask = foreground ^ background;
  2109. //XSetForeground(DisplayHandle, gc, 0xffffffff);
  2110. //XSetBackground(DisplayHandle, gc, background);
  2111. //XSetFunction(DisplayHandle, gc, GXxor);
  2112. //XSetPlaneMask(DisplayHandle, gc, mask);
  2113. gc = XCreateGC (DisplayHandle, hwnd.client_window, GCFunction.GCSubwindowMode | GCFunction.GCLineWidth | GCFunction.GCForeground, ref gc_values);
  2114. uint foreground;
  2115. uint background;
  2116. Control control;
  2117. control = Control.FromHandle (handle);
  2118. XColor xcolor = new XColor ();
  2119. xcolor.red = (ushort)(control.ForeColor.R * 257);
  2120. xcolor.green = (ushort)(control.ForeColor.G * 257);
  2121. xcolor.blue = (ushort)(control.ForeColor.B * 257);
  2122. XAllocColor (DisplayHandle, DefaultColormap, ref xcolor);
  2123. foreground = (uint)xcolor.pixel.ToInt32 ();
  2124. xcolor.red = (ushort)(control.BackColor.R * 257);
  2125. xcolor.green = (ushort)(control.BackColor.G * 257);
  2126. xcolor.blue = (ushort)(control.BackColor.B * 257);
  2127. XAllocColor (DisplayHandle, DefaultColormap, ref xcolor);
  2128. background = (uint)xcolor.pixel.ToInt32 ();
  2129. uint mask = foreground ^ background;
  2130. XSetForeground (DisplayHandle, gc, 0xffffffff);
  2131. XSetBackground (DisplayHandle, gc, background);
  2132. XSetFunction (DisplayHandle, gc, GXFunction.GXxor);
  2133. XSetPlaneMask (DisplayHandle, gc, mask);
  2134. if ((rect.Width > 0) && (rect.Height > 0)) {
  2135. XDrawRectangle (DisplayHandle, hwnd.client_window, gc, rect.Left, rect.Top, rect.Width, rect.Height);
  2136. } else {
  2137. if (rect.Width > 0) {
  2138. XDrawLine (DisplayHandle, hwnd.client_window, gc, rect.X, rect.Y, rect.Right, rect.Y);
  2139. } else {
  2140. XDrawLine (DisplayHandle, hwnd.client_window, gc, rect.X, rect.Y, rect.X, rect.Bottom);
  2141. }
  2142. }
  2143. XFreeGC (DisplayHandle, gc);
  2144. }
  2145. internal override void DoEvents ()
  2146. {
  2147. MSG msg = new MSG ();
  2148. if (OverrideCursorHandle != IntPtr.Zero) {
  2149. OverrideCursorHandle = IntPtr.Zero;
  2150. }
  2151. while (PeekMessage (ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)) {
  2152. TranslateMessage (ref msg);
  2153. DispatchMessage (ref msg);
  2154. }
  2155. }
  2156. internal override void EnableWindow (IntPtr handle, bool Enable)
  2157. {
  2158. Hwnd hwnd;
  2159. hwnd = Hwnd.ObjectFromHandle (handle);
  2160. if (hwnd != null) {
  2161. hwnd.Enabled = Enable;
  2162. }
  2163. }
  2164. internal override void EndLoop (Thread thread)
  2165. {
  2166. // This is where we one day will shut down the loop for the thread
  2167. }
  2168. internal override IntPtr GetActive ()
  2169. {
  2170. Atom actual_atom;
  2171. int actual_format;
  2172. int nitems;
  2173. int bytes_after;
  2174. IntPtr prop = IntPtr.Zero;
  2175. IntPtr active = IntPtr.Zero;
  2176. 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);
  2177. if ((nitems > 0) && (prop != IntPtr.Zero)) {
  2178. active = (IntPtr)Marshal.ReadInt32 (prop);
  2179. XFree (prop);
  2180. }
  2181. if (active != IntPtr.Zero) {
  2182. Hwnd hwnd;
  2183. hwnd = Hwnd.GetObjectFromWindow (active);
  2184. if (hwnd != null) {
  2185. active = hwnd.Handle;
  2186. } else {
  2187. active = IntPtr.Zero;
  2188. }
  2189. }
  2190. return active;
  2191. }
  2192. internal override void GetCursorInfo (IntPtr cursor, out int width, out int height, out int hotspot_x, out int hotspot_y)
  2193. {
  2194. throw new NotImplementedException ();
  2195. }
  2196. internal override void GetDisplaySize (out Size size)
  2197. {
  2198. XWindowAttributes attributes=new XWindowAttributes ();
  2199. lock (XlibLock) {
  2200. // FIXME - use _NET_WM messages instead?
  2201. XGetWindowAttributes (DisplayHandle, XRootWindow (DisplayHandle, ScreenNo), ref attributes);
  2202. }
  2203. size = new Size (attributes.width, attributes.height);
  2204. }
  2205. internal override SizeF GetAutoScaleSize (Font font)
  2206. {
  2207. Graphics g;
  2208. float width;
  2209. string magic_string = "The quick brown fox jumped over the lazy dog.";
  2210. double magic_number = 44.549996948242189;
  2211. g = Graphics.FromHwnd (FosterParent);
  2212. width = (float) (g.MeasureString (magic_string, font).Width / magic_number);
  2213. return new SizeF (width, font.Height);
  2214. }
  2215. internal override IntPtr GetParent (IntPtr handle)
  2216. {
  2217. Hwnd hwnd;
  2218. hwnd = Hwnd.ObjectFromHandle (handle);
  2219. if (hwnd != null && hwnd.parent != null) {
  2220. return hwnd.parent.Handle;
  2221. }
  2222. return IntPtr.Zero;
  2223. }
  2224. internal override void GetCursorPos (IntPtr handle, out int x, out int y)
  2225. {
  2226. IntPtr use_handle;
  2227. IntPtr root;
  2228. IntPtr child;
  2229. int root_x;
  2230. int root_y;
  2231. int win_x;
  2232. int win_y;
  2233. int keys_buttons;
  2234. if (handle != IntPtr.Zero) {
  2235. use_handle = Hwnd.ObjectFromHandle (handle).client_window;
  2236. } else {
  2237. use_handle = RootWindow;
  2238. }
  2239. lock (XlibLock) {
  2240. XQueryPointer (DisplayHandle, use_handle, out root, out child, out root_x, out root_y, out win_x, out win_y, out keys_buttons);
  2241. }
  2242. if (handle != IntPtr.Zero) {
  2243. x = win_x;
  2244. y = win_y;
  2245. } else {
  2246. x = root_x;
  2247. y = root_y;
  2248. }
  2249. }
  2250. internal override bool GetFontMetrics (Graphics g, Font font, out int ascent, out int descent)
  2251. {
  2252. return GetFontMetrics (g.GetHdc (), font.ToHfont (), out ascent, out descent);
  2253. }
  2254. internal override Point GetMenuOrigin (IntPtr handle)
  2255. {
  2256. Hwnd hwnd;
  2257. hwnd = Hwnd.ObjectFromHandle (handle);
  2258. if (hwnd != null) {
  2259. return hwnd.MenuOrigin;
  2260. }
  2261. return Point.Empty;
  2262. }
  2263. internal override bool GetMessage (ref MSG msg, IntPtr handle, int wFilterMin, int wFilterMax)
  2264. {
  2265. XEvent xevent;
  2266. bool client;
  2267. Hwnd hwnd;
  2268. ProcessNextMessage:
  2269. if (MessageQueue.Count > 0) {
  2270. xevent = (XEvent) MessageQueue.Dequeue ();
  2271. } else {
  2272. UpdateMessageQueue ();
  2273. if (MessageQueue.Count > 0) {
  2274. xevent = (XEvent) MessageQueue.Dequeue ();
  2275. } else {
  2276. if (!PostQuitState) {
  2277. msg.hwnd = IntPtr.Zero;
  2278. msg.message = Msg.WM_ENTERIDLE;
  2279. return true;
  2280. }
  2281. // We reset ourselves so GetMessage can be called again
  2282. PostQuitState = false;
  2283. return false;
  2284. }
  2285. }
  2286. // FIXME - handle filtering
  2287. hwnd = Hwnd.GetObjectFromWindow (xevent.AnyEvent.window);
  2288. // Handle messages for windows that are already or are about to be destroyed
  2289. if (hwnd == null) {
  2290. #if DriverDebug
  2291. Console.WriteLine("GetMessage(): Got message {0} for non-existent or already destroyed window {1:X}", xevent.type, xevent.AnyEvent.window.ToInt32());
  2292. #endif
  2293. goto ProcessNextMessage;
  2294. }
  2295. if (hwnd.client_window == xevent.AnyEvent.window) {
  2296. client = true;
  2297. //Console.WriteLine("Client message, sending to window {0:X}", msg.hwnd.ToInt32());
  2298. } else {
  2299. client = false;
  2300. //Console.WriteLine("Non-Client message, sending to window {0:X}", msg.hwnd.ToInt32());
  2301. }
  2302. msg.hwnd = hwnd.Handle;
  2303. //
  2304. // If you add a new event to this switch make sure to add it in
  2305. // UpdateMessage also unless it is not coming through the X event system.
  2306. //
  2307. switch (xevent.type) {
  2308. case XEventName.KeyPress: {
  2309. Keyboard.KeyEvent (FocusWindow, xevent, ref msg);
  2310. break;
  2311. }
  2312. case XEventName.KeyRelease: {
  2313. Keyboard.KeyEvent (FocusWindow, xevent, ref msg);
  2314. break;
  2315. }
  2316. case XEventName.ButtonPress: {
  2317. switch (xevent.ButtonEvent.button) {
  2318. case 1: {
  2319. MouseState |= MouseButtons.Left;
  2320. if (client) {
  2321. msg.message = Msg.WM_LBUTTONDOWN;
  2322. } else {
  2323. msg.message = Msg.WM_NCLBUTTONDOWN;
  2324. WholeToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
  2325. }
  2326. // TODO: For WM_NCLBUTTONDOWN wParam specifies a hit-test value not the virtual keys down
  2327. msg.wParam = GetMousewParam (0);
  2328. break;
  2329. }
  2330. case 2: {
  2331. MouseState |= MouseButtons.Middle;
  2332. if (client) {
  2333. msg.message = Msg.WM_MBUTTONDOWN;
  2334. } else {
  2335. msg.message = Msg.WM_NCMBUTTONDOWN;
  2336. WholeToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
  2337. }
  2338. msg.wParam = GetMousewParam (0);
  2339. break;
  2340. }
  2341. case 3: {
  2342. MouseState |= MouseButtons.Right;
  2343. if (client) {
  2344. msg.message = Msg.WM_RBUTTONDOWN;
  2345. } else {
  2346. msg.message = Msg.WM_NCRBUTTONDOWN;
  2347. WholeToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
  2348. }
  2349. msg.wParam = GetMousewParam (0);
  2350. break;
  2351. }
  2352. case 4: {
  2353. msg.message = Msg.WM_MOUSEWHEEL;
  2354. msg.wParam = GetMousewParam (120);
  2355. break;
  2356. }
  2357. case 5: {
  2358. msg.message = Msg.WM_MOUSEWHEEL;
  2359. msg.wParam = GetMousewParam (-120);
  2360. break;
  2361. }
  2362. }
  2363. msg.lParam = (IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
  2364. MousePosition.X = xevent.ButtonEvent.x;
  2365. MousePosition.Y = xevent.ButtonEvent.y;
  2366. if (!hwnd.Enabled) {
  2367. IntPtr dummy;
  2368. msg.hwnd = hwnd.EnabledHwnd;
  2369. 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);
  2370. msg.lParam = (IntPtr)(MousePosition.Y << 16 | MousePosition.X);
  2371. }
  2372. if (Grab.Hwnd != IntPtr.Zero) {
  2373. msg.hwnd = Grab.Hwnd;
  2374. }
  2375. if (!ClickPending.Pending) {
  2376. ClickPending.Pending = true;
  2377. ClickPending.Hwnd = msg.hwnd;
  2378. ClickPending.Message = msg.message;
  2379. ClickPending.wParam = msg.wParam;
  2380. ClickPending.lParam = msg.lParam;
  2381. ClickPending.Time = (long)xevent.ButtonEvent.time;
  2382. } else {
  2383. if ((((long)xevent.ButtonEvent.time - ClickPending.Time) < DoubleClickInterval) && (msg.wParam == ClickPending.wParam) && (msg.lParam == ClickPending.lParam) && (msg.message == ClickPending.Message)) {
  2384. // Looks like a genuine double click, clicked twice on the same spot with the same keys
  2385. switch (xevent.ButtonEvent.button) {
  2386. case 1: {
  2387. msg.message = client ? Msg.WM_LBUTTONDBLCLK : Msg.WM_NCLBUTTONDBLCLK;
  2388. break;
  2389. }
  2390. case 2: {
  2391. msg.message = client ? Msg.WM_MBUTTONDBLCLK : Msg.WM_NCMBUTTONDBLCLK;
  2392. break;
  2393. }
  2394. case 3: {
  2395. msg.message = client ? Msg.WM_RBUTTONDBLCLK : Msg.WM_NCRBUTTONDBLCLK;
  2396. break;
  2397. }
  2398. }
  2399. }
  2400. ClickPending.Pending = false;
  2401. }
  2402. break;
  2403. }
  2404. case XEventName.ButtonRelease: {
  2405. Dnd.HandleButtonRelease (ref xevent);
  2406. switch (xevent.ButtonEvent.button) {
  2407. case 1: {
  2408. if (client) {
  2409. msg.message = Msg.WM_LBUTTONUP;
  2410. } else {
  2411. msg.message = Msg.WM_NCLBUTTONUP;
  2412. WholeToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
  2413. }
  2414. msg.wParam = GetMousewParam (0);
  2415. MouseState &= ~MouseButtons.Left;
  2416. break;
  2417. }
  2418. case 2: {
  2419. if (client) {
  2420. msg.message = Msg.WM_MBUTTONUP;
  2421. } else {
  2422. msg.message = Msg.WM_NCMBUTTONUP;
  2423. WholeToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
  2424. }
  2425. msg.wParam = GetMousewParam (0);
  2426. MouseState &= ~MouseButtons.Middle;
  2427. break;
  2428. }
  2429. case 3: {
  2430. if (client) {
  2431. msg.message = Msg.WM_RBUTTONUP;
  2432. } else {
  2433. msg.message = Msg.WM_NCRBUTTONUP;
  2434. WholeToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
  2435. }
  2436. msg.wParam = GetMousewParam (0);
  2437. MouseState &= ~MouseButtons.Right;
  2438. break;
  2439. }
  2440. case 4: {
  2441. goto ProcessNextMessage;
  2442. }
  2443. case 5: {
  2444. goto ProcessNextMessage;
  2445. }
  2446. }
  2447. if (!hwnd.Enabled) {
  2448. IntPtr dummy;
  2449. msg.hwnd = hwnd.EnabledHwnd;
  2450. 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);
  2451. msg.lParam = (IntPtr)(MousePosition.Y << 16 | MousePosition.X);
  2452. }
  2453. if (Grab.Hwnd != IntPtr.Zero) {
  2454. msg.hwnd = Grab.Hwnd;
  2455. }
  2456. msg.lParam = (IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
  2457. MousePosition.X = xevent.ButtonEvent.x;
  2458. MousePosition.Y = xevent.ButtonEvent.y;
  2459. break;
  2460. }
  2461. case XEventName.MotionNotify: {
  2462. if (client) {
  2463. #if DriverDebugExtra
  2464. 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);
  2465. #endif
  2466. if (Dnd.HandleMotionNotify (ref xevent))
  2467. goto ProcessNextMessage;
  2468. if (Grab.Hwnd != IntPtr.Zero) {
  2469. msg.hwnd = Grab.Hwnd;
  2470. } else {
  2471. NativeWindow.WndProc (msg.hwnd, Msg.WM_SETCURSOR, msg.hwnd, (IntPtr)HitTest.HTCLIENT);
  2472. }
  2473. msg.message = Msg.WM_MOUSEMOVE;
  2474. msg.wParam = GetMousewParam (0);
  2475. msg.lParam = (IntPtr) (xevent.MotionEvent.y << 16 | xevent.MotionEvent.x & 0xFFFF);
  2476. if (!hwnd.Enabled) {
  2477. IntPtr dummy;
  2478. msg.hwnd = hwnd.EnabledHwnd;
  2479. 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);
  2480. msg.lParam = (IntPtr)(MousePosition.Y << 16 | MousePosition.X);
  2481. }
  2482. HoverState.X = MousePosition.X = xevent.MotionEvent.x;
  2483. HoverState.Y = MousePosition.Y = xevent.MotionEvent.y;
  2484. break;
  2485. } else {
  2486. #if DriverDebugExtra
  2487. 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);
  2488. #endif
  2489. msg.message = Msg.WM_NCMOUSEMOVE;
  2490. msg.lParam = (IntPtr) (xevent.MotionEvent.y << 16 | xevent.MotionEvent.x & 0xFFFF);
  2491. if (!hwnd.Enabled) {
  2492. IntPtr dummy;
  2493. msg.hwnd = hwnd.EnabledHwnd;
  2494. 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);
  2495. msg.lParam = (IntPtr)(MousePosition.Y << 16 | MousePosition.X);
  2496. }
  2497. #if notyet
  2498. // Not sure we need this...
  2499. HitTest ht;
  2500. ht = NativeWindow.WndProc(hwnd.client_window, Msg.WM_NCHITTEST, IntPtr.Zero, msg.lParam);
  2501. #endif
  2502. MousePosition.X = xevent.MotionEvent.x;
  2503. MousePosition.Y = xevent.MotionEvent.y;
  2504. }
  2505. break;
  2506. }
  2507. case XEventName.EnterNotify: {
  2508. if (!hwnd.Enabled) {
  2509. goto ProcessNextMessage;
  2510. }
  2511. if (xevent.CrossingEvent.mode != NotifyMode.NotifyNormal) {
  2512. goto ProcessNextMessage;
  2513. }
  2514. msg.message = Msg.WM_MOUSE_ENTER;
  2515. HoverState.Timer.Enabled = true;
  2516. HoverState.Window = xevent.CrossingEvent.window;
  2517. break;
  2518. }
  2519. case XEventName.LeaveNotify: {
  2520. if (!hwnd.Enabled) {
  2521. goto ProcessNextMessage;
  2522. }
  2523. if (xevent.CrossingEvent.mode != NotifyMode.NotifyNormal) {
  2524. goto ProcessNextMessage;
  2525. }
  2526. msg.message = Msg.WM_MOUSELEAVE;
  2527. HoverState.Timer.Enabled = false;
  2528. HoverState.Window = IntPtr.Zero;
  2529. break;
  2530. }
  2531. #if later
  2532. case XEventName.CreateNotify: {
  2533. if (client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {
  2534. msg.message = WM_CREATE;
  2535. // Set up CreateStruct
  2536. } else {
  2537. goto ProcessNextMessage;
  2538. }
  2539. break;
  2540. }
  2541. #endif
  2542. case XEventName.ReparentNotify: {
  2543. if (hwnd.parent == null) { // Toplevel
  2544. if (xevent.ReparentEvent.parent != IntPtr.Zero) {
  2545. // We need to adjust x/y
  2546. int dummy_int;
  2547. hwnd.Reparented = true;
  2548. 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);
  2549. msg.message = Msg.WM_WINDOWPOSCHANGED;
  2550. if (hwnd.opacity != 0xffffffff) {
  2551. uint opacity;
  2552. opacity = hwnd.opacity;
  2553. XChangeProperty (DisplayHandle, XGetParent (hwnd.whole_window), NetAtoms [(int)NA._NET_WM_WINDOW_OPACITY], Atom.XA_CARDINAL, 32, PropertyMode.Replace, ref opacity, 1);
  2554. }
  2555. } else {
  2556. hwnd.Reparented = false;
  2557. goto ProcessNextMessage;
  2558. }
  2559. }
  2560. break;
  2561. }
  2562. case XEventName.ConfigureNotify: {
  2563. if (!client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) { // Ignore events for children (SubstructureNotify) and client areas
  2564. XplatUIWin32.NCCALCSIZE_PARAMS ncp;
  2565. IntPtr ptr;
  2566. Rectangle rect;
  2567. #if DriverDebugExtra
  2568. 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);
  2569. #endif
  2570. msg.message = Msg.WM_WINDOWPOSCHANGED;
  2571. hwnd.configure_pending = false;
  2572. // We need to adjust our client window to track the resize of whole_window
  2573. rect = hwnd.DefaultClientRect;
  2574. ncp = new XplatUIWin32.NCCALCSIZE_PARAMS ();
  2575. ptr = Marshal.AllocHGlobal (Marshal.SizeOf (ncp));
  2576. ncp.rgrc1.left = rect.Left;
  2577. ncp.rgrc1.top = rect.Top;
  2578. ncp.rgrc1.right = rect.Right;
  2579. ncp.rgrc1.bottom = rect.Bottom;
  2580. Marshal.StructureToPtr (ncp, ptr, true);
  2581. NativeWindow.WndProc (hwnd.client_window, Msg.WM_NCCALCSIZE, (IntPtr)1, ptr);
  2582. ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure (ptr, typeof(XplatUIWin32.NCCALCSIZE_PARAMS));
  2583. Marshal.FreeHGlobal (ptr);
  2584. // FIXME - debug this with Menus, need to set hwnd.ClientRect
  2585. rect = new Rectangle (ncp.rgrc1.left, ncp.rgrc1.top, ncp.rgrc1.right - ncp.rgrc1.left, ncp.rgrc1.bottom - ncp.rgrc1.top);
  2586. //Console.WriteLine("CreateOffscreenbuffer...");
  2587. // CreateOffscreenBuffer (ref hwnd.client_offscreen, rect.Width, rect.Height);
  2588. XMoveResizeWindow (DisplayHandle, hwnd.client_window, rect.X, rect.Y, rect.Width, rect.Height);
  2589. } else {
  2590. goto ProcessNextMessage;
  2591. }
  2592. msg.lParam = IntPtr.Zero; // FIXME - Generate LPWINDOWPOS structure and pass on
  2593. break;
  2594. }
  2595. case XEventName.FocusIn: {
  2596. if (!hwnd.Enabled) {
  2597. goto ProcessNextMessage;
  2598. }
  2599. msg.message = Msg.WM_SETFOCUS;
  2600. msg.wParam = IntPtr.Zero;
  2601. break;
  2602. }
  2603. case XEventName.FocusOut: {
  2604. if (!hwnd.Enabled) {
  2605. goto ProcessNextMessage;
  2606. }
  2607. msg.message = Msg.WM_KILLFOCUS;
  2608. msg.wParam = IntPtr.Zero;
  2609. break;
  2610. }
  2611. case XEventName.Expose: {
  2612. if (PostQuitState) {
  2613. goto ProcessNextMessage;
  2614. }
  2615. if (client) {
  2616. if (!hwnd.expose_pending) {
  2617. goto ProcessNextMessage;
  2618. }
  2619. } else {
  2620. if (!hwnd.nc_expose_pending) {
  2621. goto ProcessNextMessage;
  2622. }
  2623. switch (hwnd.border_style) {
  2624. case FormBorderStyle.Fixed3D: {
  2625. Graphics g;
  2626. g = Graphics.FromHwnd (hwnd.whole_window);
  2627. ControlPaint.DrawBorder3D (g, new Rectangle (0, 0, hwnd.Width, hwnd.Height));
  2628. g.Dispose ();
  2629. break;
  2630. }
  2631. case FormBorderStyle.FixedSingle: {
  2632. Graphics g;
  2633. g = Graphics.FromHwnd (hwnd.whole_window);
  2634. ControlPaint.DrawBorder (g, new Rectangle (0, 0, hwnd.Width, hwnd.Height), Color.Black, ButtonBorderStyle.Solid);
  2635. g.Dispose ();
  2636. break;
  2637. }
  2638. }
  2639. #if DriverDebugExtra
  2640. 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);
  2641. #endif
  2642. Rectangle rect = new Rectangle (xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
  2643. Region region = new Region (rect);
  2644. IntPtr hrgn = region.GetHrgn (null); // Graphics object isn't needed
  2645. msg.message = Msg.WM_NCPAINT;
  2646. msg.wParam = hrgn;
  2647. hwnd.nc_expose_pending = false;
  2648. break;
  2649. }
  2650. #if DriverDebugExtra
  2651. 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);
  2652. #endif
  2653. if (Caret.Visible == 1) {
  2654. Caret.Paused = true;
  2655. HideCaret ();
  2656. }
  2657. if (Caret.Visible == 1) {
  2658. ShowCaret ();
  2659. Caret.Paused = false;
  2660. }
  2661. msg.message = Msg.WM_PAINT;
  2662. break;
  2663. }
  2664. case XEventName.DestroyNotify: {
  2665. // This is a bit tricky, we don't receive our own DestroyNotify, we only get those for our children
  2666. hwnd = Hwnd.ObjectFromHandle (xevent.DestroyWindowEvent.window);
  2667. // We may get multiple for the same window, act only one the first (when Hwnd still knows about it)
  2668. if (hwnd.client_window == xevent.DestroyWindowEvent.window) {
  2669. msg.hwnd = hwnd.client_window;
  2670. msg.message = Msg.WM_DESTROY;
  2671. hwnd.Dispose ();
  2672. #if DriverDebug
  2673. Console.WriteLine("Got DestroyNotify on Window {0:X}", msg.hwnd.ToInt32());
  2674. #endif
  2675. } else {
  2676. goto ProcessNextMessage;
  2677. }
  2678. break;
  2679. }
  2680. case XEventName.ClientMessage: {
  2681. if (Dnd.HandleClientMessage (ref xevent)) {
  2682. goto ProcessNextMessage;
  2683. }
  2684. if (xevent.ClientMessageEvent.message_type == (IntPtr)AsyncAtom) {
  2685. XplatUIDriverSupport.ExecuteClientMessage ((GCHandle)xevent.ClientMessageEvent.ptr1);
  2686. break;
  2687. }
  2688. if (xevent.ClientMessageEvent.message_type == (IntPtr)HoverState.Atom) {
  2689. msg.message = Msg.WM_MOUSEHOVER;
  2690. msg.wParam = GetMousewParam (0);
  2691. msg.lParam = (IntPtr) (xevent.ClientMessageEvent.ptr1);
  2692. break;
  2693. }
  2694. if (xevent.ClientMessageEvent.message_type == (IntPtr)PostAtom) {
  2695. msg.hwnd = xevent.ClientMessageEvent.ptr1;
  2696. msg.message = (Msg) xevent.ClientMessageEvent.ptr2.ToInt32 ();
  2697. msg.wParam = xevent.ClientMessageEvent.ptr3;
  2698. msg.lParam = xevent.ClientMessageEvent.ptr4;
  2699. break;
  2700. }
  2701. #if dontcare
  2702. if (xevent.ClientMessageEvent.message_type == (IntPtr)NetAtoms[(int)NA._XEMBED]) {
  2703. Console.WriteLine("GOT EMBED MESSAGE {0:X}", xevent.ClientMessageEvent.ptr2.ToInt32());
  2704. break;
  2705. }
  2706. #endif
  2707. if (xevent.ClientMessageEvent.message_type == (IntPtr)NetAtoms [(int)NA.WM_PROTOCOLS]) {
  2708. if (xevent.ClientMessageEvent.ptr1 == (IntPtr)NetAtoms [(int)NA.WM_DELETE_WINDOW]) {
  2709. msg.message = Msg.WM_CLOSE;
  2710. Graphics.FromHdcInternal (IntPtr.Zero);
  2711. break;
  2712. }
  2713. // We should not get this, but I'll leave the code in case we need it in the future
  2714. if (xevent.ClientMessageEvent.ptr1 == (IntPtr)NetAtoms [(int)NA.WM_TAKE_FOCUS]) {
  2715. goto ProcessNextMessage;
  2716. }
  2717. }
  2718. break;
  2719. }
  2720. case XEventName.TimerNotify: {
  2721. xevent.TimerNotifyEvent.handler (this, EventArgs.Empty);
  2722. break;
  2723. }
  2724. default: {
  2725. goto ProcessNextMessage;
  2726. }
  2727. }
  2728. return true;
  2729. }
  2730. internal override bool GetText (IntPtr handle, out string text)
  2731. {
  2732. IntPtr textptr;
  2733. textptr = IntPtr.Zero;
  2734. lock (XlibLock) {
  2735. // FIXME - use _NET properties
  2736. XFetchName (DisplayHandle, Hwnd.ObjectFromHandle (handle).whole_window, ref textptr);
  2737. }
  2738. if (textptr != IntPtr.Zero) {
  2739. text = Marshal.PtrToStringAnsi (textptr);
  2740. XFree (textptr);
  2741. return true;
  2742. } else {
  2743. text = "";
  2744. return false;
  2745. }
  2746. }
  2747. 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)
  2748. {
  2749. Hwnd hwnd;
  2750. Rectangle rect;
  2751. hwnd = Hwnd.ObjectFromHandle (handle);
  2752. if (hwnd != null) {
  2753. x = hwnd.x;
  2754. y = hwnd.y;
  2755. width = hwnd.width;
  2756. height = hwnd.height;
  2757. rect = Hwnd.GetClientRectangle (hwnd.border_style, hwnd.menu, hwnd.title_style, hwnd.caption_height, hwnd.tool_caption_height, width, height);
  2758. client_width = rect.Width;
  2759. client_height = rect.Height;
  2760. return;
  2761. }
  2762. // Should we throw an exception or fail silently?
  2763. // throw new ArgumentException("Called with an invalid window handle", "handle");
  2764. x = 0;
  2765. y = 0;
  2766. width = 0;
  2767. height = 0;
  2768. client_width = 0;
  2769. client_height = 0;
  2770. }
  2771. internal override FormWindowState GetWindowState (IntPtr handle)
  2772. {
  2773. Atom actual_atom;
  2774. int actual_format;
  2775. int nitems;
  2776. int bytes_after;
  2777. IntPtr prop = IntPtr.Zero;
  2778. IntPtr atom;
  2779. int maximized;
  2780. bool minimized;
  2781. XWindowAttributes attributes;
  2782. Hwnd hwnd;
  2783. hwnd = Hwnd.ObjectFromHandle (handle);
  2784. maximized = 0;
  2785. minimized = false;
  2786. 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);
  2787. if ((nitems > 0) && (prop != IntPtr.Zero)) {
  2788. for (int i = 0; i < nitems; i++) {
  2789. atom = (IntPtr)Marshal.ReadInt32 (prop, i * 4);
  2790. if ((atom == (IntPtr)NetAtoms [(int)NA._NET_WM_STATE_MAXIMIZED_HORZ]) || (atom == (IntPtr)NetAtoms [(int)NA._NET_WM_STATE_MAXIMIZED_VERT])) {
  2791. maximized++;
  2792. } else if (atom == (IntPtr)NetAtoms [(int)NA._NET_WM_STATE_HIDDEN]) {
  2793. minimized = true;
  2794. }
  2795. }
  2796. XFree (prop);
  2797. }
  2798. if (minimized) {
  2799. return FormWindowState.Minimized;
  2800. } else if (maximized == 2) {
  2801. return FormWindowState.Maximized;
  2802. }
  2803. attributes = new XWindowAttributes ();
  2804. XGetWindowAttributes (DisplayHandle, handle, ref attributes);
  2805. if (attributes.map_state == MapState.IsUnmapped) {
  2806. throw new NotSupportedException ("Cannot retrieve the state of an unmapped window");
  2807. }
  2808. return FormWindowState.Normal;
  2809. }
  2810. internal override void GrabInfo (out IntPtr handle, out bool GrabConfined, out Rectangle GrabArea)
  2811. {
  2812. handle = Grab.Hwnd;
  2813. GrabConfined = Grab.Confined;
  2814. GrabArea = Grab.Area;
  2815. }
  2816. internal override void GrabWindow (IntPtr handle, IntPtr confine_to_handle)
  2817. {
  2818. Hwnd hwnd;
  2819. IntPtr confine_to_window;
  2820. confine_to_window = IntPtr.Zero;
  2821. if (confine_to_handle != IntPtr.Zero) {
  2822. XWindowAttributes attributes = new XWindowAttributes ();
  2823. hwnd = Hwnd.ObjectFromHandle (confine_to_handle);
  2824. lock (XlibLock) {
  2825. XGetWindowAttributes (DisplayHandle, hwnd.client_window, ref attributes);
  2826. }
  2827. Grab.Area.X = attributes.x;
  2828. Grab.Area.Y = attributes.y;
  2829. Grab.Area.Width = attributes.width;
  2830. Grab.Area.Height = attributes.height;
  2831. Grab.Confined = true;
  2832. confine_to_window = hwnd.client_window;
  2833. }
  2834. Grab.Hwnd = handle;
  2835. hwnd = Hwnd.ObjectFromHandle (handle);
  2836. lock (XlibLock) {
  2837. XGrabPointer (DisplayHandle, hwnd.client_window, false,
  2838. EventMask.ButtonPressMask | EventMask.ButtonMotionMask |
  2839. EventMask.ButtonReleaseMask | EventMask.PointerMotionMask,
  2840. GrabMode.GrabModeAsync, GrabMode.GrabModeAsync, confine_to_window, 0, 0);
  2841. }
  2842. }
  2843. internal override void UngrabWindow (IntPtr hwnd)
  2844. {
  2845. lock (XlibLock) {
  2846. XUngrabPointer (DisplayHandle, 0);
  2847. XFlush (DisplayHandle);
  2848. }
  2849. Grab.Hwnd = IntPtr.Zero;
  2850. Grab.Confined = false;
  2851. }
  2852. internal override void HandleException (Exception e)
  2853. {
  2854. StackTrace st = new StackTrace (e, true);
  2855. Console.WriteLine ("Exception '{0}'", e.Message + st.ToString ());
  2856. Console.WriteLine ("{0}{1}", e.Message, st.ToString ());
  2857. }
  2858. internal override void Invalidate (IntPtr handle, Rectangle rc, bool clear)
  2859. {
  2860. Hwnd hwnd;
  2861. XEvent xevent;
  2862. hwnd = Hwnd.ObjectFromHandle (handle);
  2863. xevent = new XEvent ();
  2864. xevent.type = XEventName.Expose;
  2865. xevent.ExposeEvent.display = DisplayHandle;
  2866. xevent.ExposeEvent.window = hwnd.client_window;
  2867. if (clear) {
  2868. xevent.ExposeEvent.x = hwnd.X;
  2869. xevent.ExposeEvent.y = hwnd.Y;
  2870. xevent.ExposeEvent.width = hwnd.Width;
  2871. xevent.ExposeEvent.height = hwnd.Height;
  2872. } else {
  2873. xevent.ExposeEvent.x = rc.X;
  2874. xevent.ExposeEvent.y = rc.Y;
  2875. xevent.ExposeEvent.width = rc.Width;
  2876. xevent.ExposeEvent.height = rc.Height;
  2877. }
  2878. AddExpose (xevent);
  2879. }
  2880. internal override bool IsEnabled (IntPtr handle)
  2881. {
  2882. return Hwnd.ObjectFromHandle (handle).Enabled;
  2883. }
  2884. internal override bool IsVisible (IntPtr handle)
  2885. {
  2886. return Hwnd.ObjectFromHandle (handle).visible;
  2887. }
  2888. internal override void KillTimer (Timer timer)
  2889. {
  2890. lock (TimerList) {
  2891. TimerList.Remove (timer);
  2892. }
  2893. }
  2894. internal override void MenuToScreen (IntPtr handle, ref int x, ref int y)
  2895. {
  2896. int dest_x_return;
  2897. int dest_y_return;
  2898. IntPtr child;
  2899. Hwnd hwnd;
  2900. hwnd = Hwnd.ObjectFromHandle (handle);
  2901. lock (XlibLock) {
  2902. XTranslateCoordinates (DisplayHandle, hwnd.whole_window, RootWindow, x, y, out dest_x_return, out dest_y_return, out child);
  2903. }
  2904. x = dest_x_return;
  2905. y = dest_y_return;
  2906. }
  2907. internal override void OverrideCursor (IntPtr cursor)
  2908. {
  2909. OverrideCursorHandle = cursor;
  2910. }
  2911. internal override PaintEventArgs PaintEventStart (IntPtr handle, bool client)
  2912. {
  2913. PaintEventArgs paint_event;
  2914. Hwnd hwnd;
  2915. hwnd = Hwnd.ObjectFromHandle (handle);
  2916. if (Caret.Visible == 1) {
  2917. Caret.Paused = true;
  2918. HideCaret ();
  2919. }
  2920. if (client) {
  2921. // handle backing store
  2922. IntPtr gdk_window = gdk_window_lookup (hwnd.client_window);
  2923. IntPtr gdk_pixmap = NewPixmap (gdk_window, hwnd.ClientRect.Width, hwnd.ClientRect.Height);
  2924. backing_store [gdk_window] = gdk_pixmap;
  2925. hwnd.client_dc = Graphics.FromHwnd (gdk_x11_drawable_get_xid (gdk_pixmap));
  2926. hwnd.client_dc.SetClip (hwnd.invalid);
  2927. paint_event = new PaintEventArgs (hwnd.client_dc, hwnd.invalid);
  2928. hwnd.expose_pending = false;
  2929. return paint_event;
  2930. } else {
  2931. hwnd.client_dc = Graphics.FromHwnd (hwnd.whole_window);
  2932. paint_event = new PaintEventArgs (hwnd.client_dc, new Rectangle (0, 0, hwnd.width, hwnd.height));
  2933. hwnd.nc_expose_pending = false;
  2934. return paint_event;
  2935. }
  2936. }
  2937. internal override void PaintEventEnd (IntPtr handle, bool client)
  2938. {
  2939. Hwnd hwnd;
  2940. hwnd = Hwnd.ObjectFromHandle (handle);
  2941. hwnd.client_dc.Flush ();
  2942. if (client) {
  2943. // clients are already drawn to a backing store pixmap
  2944. IntPtr gdk_window = gdk_window_lookup (hwnd.client_window);
  2945. IntPtr gdk_pixmap = (IntPtr)backing_store [gdk_window];
  2946. BlitOffscreenPixmap (gdk_pixmap, gdk_window, hwnd.Invalid);
  2947. g_object_unref (gdk_pixmap);
  2948. backing_store.Remove (gdk_pixmap);
  2949. hwnd.ClearInvalidArea ();
  2950. }
  2951. hwnd.client_dc.Dispose ();
  2952. hwnd.client_dc = null;
  2953. if (Caret.Visible == 1) {
  2954. ShowCaret ();
  2955. Caret.Paused = false;
  2956. }
  2957. }
  2958. internal override bool PeekMessage (ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags)
  2959. {
  2960. bool pending;
  2961. // FIXME - imlement filtering
  2962. if ((flags & (uint)PeekMessageFlags.PM_REMOVE) == 0) {
  2963. throw new NotImplementedException ("PeekMessage PM_NOREMOVE is not implemented yet"); // FIXME - Implement PM_NOREMOVE flag
  2964. }
  2965. pending = false;
  2966. if (MessageQueue.Count > 0) {
  2967. pending = true;
  2968. } else {
  2969. // Only call UpdateMessageQueue if real events are pending
  2970. // otherwise we go to sleep on the socket
  2971. if (XPending (DisplayHandle) != 0) {
  2972. UpdateMessageQueue ();
  2973. pending = true;
  2974. }
  2975. }
  2976. CheckTimers (DateTime.Now);
  2977. if (!pending) {
  2978. return false;
  2979. }
  2980. return GetMessage (ref msg, hWnd, wFilterMin, wFilterMax);
  2981. }
  2982. // FIXME - I think this should just enqueue directly
  2983. internal override bool PostMessage (IntPtr handle, Msg message, IntPtr wparam, IntPtr lparam)
  2984. {
  2985. XEvent xevent = new XEvent ();
  2986. Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
  2987. xevent.type = XEventName.ClientMessage;
  2988. xevent.ClientMessageEvent.display = DisplayHandle;
  2989. if (hwnd != null) {
  2990. xevent.ClientMessageEvent.window = hwnd.whole_window;
  2991. } else {
  2992. xevent.ClientMessageEvent.window = IntPtr.Zero;
  2993. }
  2994. xevent.ClientMessageEvent.message_type = (IntPtr) PostAtom;
  2995. xevent.ClientMessageEvent.format = 32;
  2996. xevent.ClientMessageEvent.ptr1 = handle;
  2997. xevent.ClientMessageEvent.ptr2 = (IntPtr) message;
  2998. xevent.ClientMessageEvent.ptr3 = wparam;
  2999. xevent.ClientMessageEvent.ptr4 = lparam;
  3000. MessageQueue.Enqueue (xevent);
  3001. return true;
  3002. }
  3003. internal override void PostQuitMessage (int exitCode)
  3004. {
  3005. XFlush (DisplayHandle);
  3006. PostQuitState = true;
  3007. // Remove our display handle from S.D
  3008. Graphics.FromHdcInternal (IntPtr.Zero);
  3009. }
  3010. internal override void ScreenToClient (IntPtr handle, ref int x, ref int y)
  3011. {
  3012. int dest_x_return;
  3013. int dest_y_return;
  3014. IntPtr child;
  3015. Hwnd hwnd;
  3016. hwnd = Hwnd.ObjectFromHandle (handle);
  3017. lock (XlibLock) {
  3018. XTranslateCoordinates (DisplayHandle, RootWindow, hwnd.client_window, x, y, out dest_x_return, out dest_y_return, out child);
  3019. }
  3020. x = dest_x_return;
  3021. y = dest_y_return;
  3022. }
  3023. internal override void ScreenToMenu (IntPtr handle, ref int x, ref int y)
  3024. {
  3025. int dest_x_return;
  3026. int dest_y_return;
  3027. IntPtr child;
  3028. Hwnd hwnd;
  3029. hwnd = Hwnd.ObjectFromHandle (handle);
  3030. lock (XlibLock) {
  3031. XTranslateCoordinates (DisplayHandle, RootWindow, hwnd.whole_window, x, y, out dest_x_return, out dest_y_return, out child);
  3032. }
  3033. x = dest_x_return;
  3034. y = dest_y_return;
  3035. }
  3036. internal override void ScrollWindow (IntPtr handle, Rectangle area, int XAmount, int YAmount, bool with_children)
  3037. {
  3038. Hwnd hwnd;
  3039. IntPtr gc;
  3040. XGCValues gc_values;
  3041. hwnd = Hwnd.ObjectFromHandle (handle);
  3042. if (hwnd.invalid != Rectangle.Empty) {
  3043. // BIG FAT WARNING. This only works with how we use this function right now
  3044. // where we basically still scroll the whole window, but work around areas
  3045. // that are covered by our children
  3046. hwnd.invalid.X += XAmount;
  3047. hwnd.invalid.Y += YAmount;
  3048. if (hwnd.invalid.X < 0) {
  3049. hwnd.invalid.Width += hwnd.invalid.X;
  3050. hwnd.invalid.X = 0;
  3051. }
  3052. if (hwnd.invalid.Y < 0) {
  3053. hwnd.invalid.Height += hwnd.invalid.Y;
  3054. hwnd.invalid.Y = 0;
  3055. }
  3056. }
  3057. gc_values = new XGCValues ();
  3058. if (with_children) {
  3059. gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
  3060. }
  3061. gc = XCreateGC (DisplayHandle, hwnd.client_window, 0, ref gc_values);
  3062. XCopyArea (DisplayHandle, hwnd.client_window, hwnd.client_window, gc, area.X - XAmount, area.Y - YAmount, area.Width, area.Height, area.X, area.Y);
  3063. // Generate an expose for the area exposed by the horizontal scroll
  3064. if (XAmount > 0) {
  3065. hwnd.AddInvalidArea (area.X, area.Y, XAmount, area.Height);
  3066. } else if (XAmount < 0) {
  3067. hwnd.AddInvalidArea (XAmount + area.X + area.Width, area.Y, -XAmount, area.Height);
  3068. }
  3069. // Generate an expose for the area exposed by the vertical scroll
  3070. if (YAmount > 0) {
  3071. hwnd.AddInvalidArea (area.X, area.Y, area.Width, YAmount);
  3072. } else if (YAmount < 0) {
  3073. hwnd.AddInvalidArea (area.X, YAmount + area.Y + area.Height, area.Width, -YAmount);
  3074. }
  3075. XFreeGC (DisplayHandle, gc);
  3076. UpdateWindow (handle);
  3077. }
  3078. internal override void ScrollWindow (IntPtr handle, int XAmount, int YAmount, bool with_children)
  3079. {
  3080. Hwnd hwnd;
  3081. hwnd = Hwnd.GetObjectFromWindow (handle);
  3082. ScrollWindow (handle, hwnd.ClientRect, XAmount, YAmount, with_children);
  3083. }
  3084. internal override void SendAsyncMethod (AsyncMethodData method)
  3085. {
  3086. XEvent xevent = new XEvent ();
  3087. xevent.type = XEventName.ClientMessage;
  3088. xevent.ClientMessageEvent.display = DisplayHandle;
  3089. xevent.ClientMessageEvent.window = FosterParent;
  3090. xevent.ClientMessageEvent.message_type = (IntPtr)AsyncAtom;
  3091. xevent.ClientMessageEvent.format = 32;
  3092. xevent.ClientMessageEvent.ptr1 = (IntPtr) GCHandle.Alloc (method);
  3093. MessageQueue.EnqueueLocked (xevent);
  3094. WakeupMain ();
  3095. }
  3096. internal override IntPtr SendMessage (IntPtr hwnd, Msg message, IntPtr wParam, IntPtr lParam)
  3097. {
  3098. return NativeWindow.WndProc (hwnd, message, wParam, lParam);
  3099. }
  3100. internal override void SetAllowDrop (IntPtr handle, bool value)
  3101. {
  3102. // We allow drop on all windows
  3103. }
  3104. internal override DragDropEffects StartDrag (IntPtr handle, object data,
  3105. DragDropEffects allowed_effects)
  3106. {
  3107. Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
  3108. if (hwnd == null)
  3109. throw new ArgumentException ("Attempt to begin drag from invalid window handle (" + handle.ToInt32 () + ").");
  3110. return Dnd.StartDrag (hwnd.client_window, data, allowed_effects);
  3111. }
  3112. internal override void SetBorderStyle (IntPtr handle, FormBorderStyle border_style)
  3113. {
  3114. Hwnd hwnd;
  3115. hwnd = Hwnd.ObjectFromHandle (handle);
  3116. hwnd.border_style = border_style;
  3117. XMoveResizeWindow (DisplayHandle, hwnd.client_window, hwnd.ClientRect.X, hwnd.ClientRect.Y, hwnd.ClientRect.Width, hwnd.ClientRect.Height);
  3118. InvalidateWholeWindow (handle);
  3119. }
  3120. internal override void SetCaretPos (IntPtr handle, int x, int y)
  3121. {
  3122. if (Caret.Hwnd == handle) {
  3123. Caret.Timer.Stop ();
  3124. HideCaret ();
  3125. Caret.X = x;
  3126. Caret.Y = y;
  3127. if (Caret.Visible == 1) {
  3128. ShowCaret ();
  3129. Caret.Timer.Start ();
  3130. }
  3131. }
  3132. }
  3133. internal override void SetCursor (IntPtr handle, IntPtr cursor)
  3134. {
  3135. Hwnd hwnd;
  3136. if (OverrideCursorHandle == IntPtr.Zero) {
  3137. if ((LastCursorWindow == handle) && (LastCursorHandle == cursor)) {
  3138. return;
  3139. }
  3140. LastCursorHandle = cursor;
  3141. LastCursorWindow = handle;
  3142. hwnd = Hwnd.ObjectFromHandle (handle);
  3143. lock (XlibLock) {
  3144. if (cursor != IntPtr.Zero) {
  3145. XDefineCursor (DisplayHandle, hwnd.whole_window, cursor);
  3146. } else {
  3147. XUndefineCursor (DisplayHandle, hwnd.whole_window);
  3148. }
  3149. }
  3150. return;
  3151. }
  3152. hwnd = Hwnd.ObjectFromHandle (handle);
  3153. lock (XlibLock) {
  3154. XDefineCursor (DisplayHandle, hwnd.whole_window, OverrideCursorHandle);
  3155. }
  3156. }
  3157. internal override void SetCursorPos (IntPtr handle, int x, int y)
  3158. {
  3159. if (handle == IntPtr.Zero) {
  3160. lock (XlibLock) {
  3161. XWarpPointer (DisplayHandle, IntPtr.Zero, IntPtr.Zero, 0, 0, 0, 0, x, y);
  3162. }
  3163. return;
  3164. } else {
  3165. Hwnd hwnd;
  3166. hwnd = Hwnd.ObjectFromHandle (handle);
  3167. lock (XlibLock) {
  3168. XWarpPointer (DisplayHandle, IntPtr.Zero, hwnd.client_window, 0, 0, 0, 0, x, y);
  3169. }
  3170. return;
  3171. }
  3172. }
  3173. internal override void SetFocus (IntPtr handle)
  3174. {
  3175. Hwnd hwnd;
  3176. hwnd = Hwnd.ObjectFromHandle (handle);
  3177. if (FocusWindow != IntPtr.Zero) {
  3178. PostMessage (FocusWindow, Msg.WM_KILLFOCUS, hwnd.client_window, IntPtr.Zero);
  3179. }
  3180. PostMessage (hwnd.client_window, Msg.WM_SETFOCUS, FocusWindow, IntPtr.Zero);
  3181. FocusWindow = hwnd.client_window;
  3182. //XSetInputFocus(DisplayHandle, Hwnd.ObjectFromHandle(handle).client_window, RevertTo.None, IntPtr.Zero);
  3183. }
  3184. internal override void SetIcon (IntPtr handle, Icon icon)
  3185. {
  3186. Hwnd hwnd;
  3187. hwnd = Hwnd.ObjectFromHandle (handle);
  3188. if (hwnd != null) {
  3189. SetIcon (hwnd, icon);
  3190. }
  3191. }
  3192. internal override void SetMenu (IntPtr handle, Menu menu)
  3193. {
  3194. Hwnd hwnd;
  3195. hwnd = Hwnd.ObjectFromHandle (handle);
  3196. hwnd.menu = menu;
  3197. // FIXME - do we need to trigger some resize?
  3198. }
  3199. internal override void SetModal (IntPtr handle, bool Modal)
  3200. {
  3201. if (Modal) {
  3202. ModalWindows.Push (handle);
  3203. } else {
  3204. if (ModalWindows.Contains (handle)) {
  3205. ModalWindows.Pop ();
  3206. }
  3207. if (ModalWindows.Count > 0) {
  3208. Activate ((IntPtr)ModalWindows.Peek ());
  3209. }
  3210. }
  3211. }
  3212. internal override IntPtr SetParent (IntPtr handle, IntPtr parent)
  3213. {
  3214. Hwnd hwnd;
  3215. hwnd = Hwnd.ObjectFromHandle (handle);
  3216. hwnd.parent = Hwnd.ObjectFromHandle (parent);
  3217. lock (XlibLock) {
  3218. #if DriverDebug
  3219. 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());
  3220. #endif
  3221. XReparentWindow (DisplayHandle, hwnd.whole_window, hwnd.parent.client_window, hwnd.x, hwnd.y);
  3222. }
  3223. return IntPtr.Zero;
  3224. }
  3225. internal override void SetTimer (Timer timer)
  3226. {
  3227. lock (TimerList) {
  3228. TimerList.Add (timer);
  3229. }
  3230. WakeupMain ();
  3231. }
  3232. internal override bool SetTopmost (IntPtr handle, IntPtr handle_owner, bool enabled)
  3233. {
  3234. Hwnd hwnd;
  3235. Hwnd hwnd_owner;
  3236. hwnd = Hwnd.ObjectFromHandle (handle);
  3237. if (handle_owner != IntPtr.Zero) {
  3238. hwnd_owner = Hwnd.ObjectFromHandle (handle_owner);
  3239. } else {
  3240. hwnd_owner = null;
  3241. }
  3242. if (enabled) {
  3243. lock (XlibLock) {
  3244. if (hwnd_owner != null) {
  3245. XSetTransientForHint (DisplayHandle, hwnd.whole_window, hwnd_owner.whole_window);
  3246. } else {
  3247. XSetTransientForHint (DisplayHandle, hwnd.whole_window, FosterParent);
  3248. }
  3249. }
  3250. } else {
  3251. lock (XlibLock) {
  3252. XDeleteProperty (DisplayHandle, hwnd.whole_window, (int)Atom.XA_WM_TRANSIENT_FOR);
  3253. }
  3254. }
  3255. return true;
  3256. }
  3257. internal override bool SetVisible (IntPtr handle, bool visible)
  3258. {
  3259. Hwnd hwnd;
  3260. hwnd = Hwnd.ObjectFromHandle (handle);
  3261. hwnd.visible = visible;
  3262. lock (XlibLock) {
  3263. if (visible) {
  3264. if (Control.FromHandle (handle) is Form) {
  3265. FormWindowState s;
  3266. s = ((Form)Control.FromHandle (handle)).WindowState;
  3267. XMapWindow (DisplayHandle, hwnd.whole_window);
  3268. XMapWindow (DisplayHandle, hwnd.client_window);
  3269. switch (s) {
  3270. case FormWindowState.Minimized: SetWindowState (handle, FormWindowState.Minimized); break;
  3271. case FormWindowState.Maximized: SetWindowState (handle, FormWindowState.Maximized); break;
  3272. }
  3273. } else {
  3274. XMapWindow (DisplayHandle, hwnd.whole_window);
  3275. XMapWindow (DisplayHandle, hwnd.client_window);
  3276. }
  3277. } else {
  3278. XUnmapWindow (DisplayHandle, hwnd.whole_window);
  3279. }
  3280. }
  3281. return true;
  3282. }
  3283. internal override void SetWindowMinMax (IntPtr handle, Rectangle maximized, Size min, Size max)
  3284. {
  3285. Hwnd hwnd;
  3286. XSizeHints hints;
  3287. hwnd = Hwnd.ObjectFromHandle (handle);
  3288. if (hwnd == null) {
  3289. return;
  3290. }
  3291. hints = new XSizeHints ();
  3292. if (min != Size.Empty) {
  3293. hints.flags = (IntPtr)((int)hints.flags | (int)XSizeHintsFlags.PMinSize);
  3294. hints.min_width = min.Width;
  3295. hints.min_height = min.Height;
  3296. }
  3297. if (max != Size.Empty) {
  3298. hints.flags = (IntPtr)((int)hints.flags | (int)XSizeHintsFlags.PMaxSize);
  3299. hints.max_width = max.Width;
  3300. hints.max_height = max.Height;
  3301. }
  3302. XSetWMNormalHints (DisplayHandle, hwnd.whole_window, ref hints);
  3303. if (maximized != Rectangle.Empty) {
  3304. hints.flags = (IntPtr)XSizeHintsFlags.PPosition;
  3305. hints.x = maximized.X;
  3306. hints.y = maximized.Y;
  3307. hints.width = maximized.Width;
  3308. hints.height = maximized.Height;
  3309. // Metacity does not seem to follow this constraint for maximized (zoomed) windows
  3310. XSetZoomHints (DisplayHandle, hwnd.whole_window, ref hints);
  3311. }
  3312. }
  3313. internal override void SetWindowPos (IntPtr handle, int x, int y, int width, int height)
  3314. {
  3315. Hwnd hwnd;
  3316. Rectangle client_rect;
  3317. hwnd = Hwnd.ObjectFromHandle (handle);
  3318. // X requires a sanity check for width & height; otherwise it dies
  3319. if (hwnd.zero_sized && width > 0 && height > 0) {
  3320. if (hwnd.visible) {
  3321. XMapWindow (DisplayHandle, hwnd.whole_window);
  3322. }
  3323. hwnd.zero_sized = false;
  3324. }
  3325. if (width < 1) {
  3326. hwnd.zero_sized = true;
  3327. XUnmapWindow (DisplayHandle, hwnd.whole_window);
  3328. }
  3329. if (height < 1) {
  3330. hwnd.zero_sized = true;
  3331. XUnmapWindow (DisplayHandle, hwnd.whole_window);
  3332. }
  3333. client_rect = Hwnd.GetClientRectangle (hwnd.border_style, hwnd.menu, hwnd.title_style, hwnd.caption_height, hwnd.tool_caption_height, width, height);
  3334. // Save a server roundtrip (and prevent a feedback loop)
  3335. if ((hwnd.x == x) && (hwnd.y == y) &&
  3336. (hwnd.width == width) && (hwnd.height == height) &&
  3337. (hwnd.ClientRect == client_rect)) {
  3338. return;
  3339. }
  3340. if (!hwnd.zero_sized) {
  3341. lock (XlibLock) {
  3342. XMoveResizeWindow (DisplayHandle, hwnd.whole_window, x, y, width, height);
  3343. XMoveResizeWindow (DisplayHandle, hwnd.client_window, client_rect.X, client_rect.Y, client_rect.Width, client_rect.Height);
  3344. }
  3345. }
  3346. // Prevent an old queued ConfigureNotify from setting our width with outdated data, set it now
  3347. hwnd.width = width;
  3348. hwnd.height = height;
  3349. }
  3350. internal override void SetWindowState (IntPtr handle, FormWindowState state)
  3351. {
  3352. FormWindowState current_state;
  3353. Hwnd hwnd;
  3354. hwnd = Hwnd.ObjectFromHandle (handle);
  3355. current_state = GetWindowState (handle);
  3356. if (current_state == state) {
  3357. return;
  3358. }
  3359. switch (state) {
  3360. case FormWindowState.Normal: {
  3361. lock (XlibLock) {
  3362. if (current_state == FormWindowState.Minimized) {
  3363. XMapWindow (DisplayHandle, hwnd.whole_window);
  3364. XMapWindow (DisplayHandle, hwnd.client_window);
  3365. } else if (current_state == FormWindowState.Maximized) {
  3366. 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]);
  3367. }
  3368. }
  3369. Activate (handle);
  3370. return;
  3371. }
  3372. case FormWindowState.Minimized: {
  3373. lock (XlibLock) {
  3374. if (current_state == FormWindowState.Maximized) {
  3375. 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]);
  3376. }
  3377. XIconifyWindow (DisplayHandle, hwnd.whole_window, ScreenNo);
  3378. }
  3379. return;
  3380. }
  3381. case FormWindowState.Maximized: {
  3382. lock (XlibLock) {
  3383. if (current_state == FormWindowState.Minimized) {
  3384. XMapWindow (DisplayHandle, hwnd.whole_window);
  3385. XMapWindow (DisplayHandle, hwnd.client_window);
  3386. }
  3387. 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]);
  3388. }
  3389. Activate (handle);
  3390. return;
  3391. }
  3392. }
  3393. }
  3394. internal override void SetWindowStyle (IntPtr handle, CreateParams cp)
  3395. {
  3396. Hwnd hwnd;
  3397. hwnd = Hwnd.ObjectFromHandle (handle);
  3398. SetHwndStyles (hwnd, cp);
  3399. SetWMStyles (hwnd, cp);
  3400. }
  3401. internal override void SetWindowTransparency (IntPtr handle, double transparency, Color key)
  3402. {
  3403. Hwnd hwnd;
  3404. uint opacity;
  3405. hwnd = Hwnd.ObjectFromHandle (handle);
  3406. if (hwnd == null) {
  3407. return;
  3408. }
  3409. hwnd.opacity = (uint)(0xffffffff * transparency);
  3410. opacity = hwnd.opacity;
  3411. if (hwnd.reparented) {
  3412. XChangeProperty (DisplayHandle, XGetParent (hwnd.whole_window), NetAtoms [(int)NA._NET_WM_WINDOW_OPACITY], Atom.XA_CARDINAL, 32, PropertyMode.Replace, ref opacity, 1);
  3413. }
  3414. }
  3415. internal override bool SetZOrder (IntPtr handle, IntPtr after_handle, bool top, bool bottom)
  3416. {
  3417. Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
  3418. if (top) {
  3419. lock (XlibLock) {
  3420. XRaiseWindow (DisplayHandle, hwnd.whole_window);
  3421. }
  3422. return true;
  3423. } else if (!bottom) {
  3424. Hwnd after_hwnd = null;
  3425. if (after_handle != IntPtr.Zero) {
  3426. after_hwnd = Hwnd.ObjectFromHandle (after_handle);
  3427. }
  3428. XWindowChanges values = new XWindowChanges ();
  3429. if (after_hwnd == null) {
  3430. throw new ArgumentNullException ("after_handle", "Need sibling to adjust z-order");
  3431. }
  3432. values.sibling = after_hwnd.whole_window;
  3433. values.stack_mode = StackMode.Below;
  3434. lock (XlibLock) {
  3435. XConfigureWindow (DisplayHandle, hwnd.whole_window, ChangeWindowFlags.CWStackMode | ChangeWindowFlags.CWSibling, ref values);
  3436. }
  3437. } else {
  3438. // Bottom
  3439. lock (XlibLock) {
  3440. XLowerWindow (DisplayHandle, hwnd.whole_window);
  3441. }
  3442. return true;
  3443. }
  3444. return false;
  3445. }
  3446. internal override void ShowCursor (bool show)
  3447. {
  3448. ; // FIXME - X11 doesn't 'hide' the cursor. we could create an empty cursor
  3449. }
  3450. internal override void StartLoop (Thread thread)
  3451. {
  3452. // Future place for prepping a new queue for this specific thread
  3453. }
  3454. internal override bool SupportsTransparency ()
  3455. {
  3456. // We need to check if the x compositing manager is running
  3457. return true;
  3458. }
  3459. internal override bool SystrayAdd (IntPtr handle, string tip, Icon icon, out ToolTip tt)
  3460. {
  3461. GetSystrayManagerWindow ();
  3462. if (SystrayMgrWindow != IntPtr.Zero) {
  3463. uint[] atoms;
  3464. XSizeHints size_hints;
  3465. Hwnd hwnd;
  3466. hwnd = Hwnd.ObjectFromHandle (handle);
  3467. #if DriverDebug
  3468. Console.WriteLine("Adding Systray Whole:{0:X}, Client:{1:X}", hwnd.whole_window.ToInt32(), hwnd.client_window.ToInt32());
  3469. #endif
  3470. XUnmapWindow (DisplayHandle, hwnd.whole_window);
  3471. XUnmapWindow (DisplayHandle, hwnd.client_window);
  3472. // Oh boy.
  3473. gdk_window_destroy (gdk_window_lookup (hwnd.client_window));
  3474. hwnd.client_window = hwnd.whole_window;
  3475. size_hints = new XSizeHints ();
  3476. size_hints.flags = (IntPtr)(XSizeHintsFlags.PMinSize | XSizeHintsFlags.PMaxSize | XSizeHintsFlags.PBaseSize);
  3477. size_hints.min_width = icon.Width;
  3478. size_hints.min_height = icon.Height;
  3479. size_hints.max_width = icon.Width;
  3480. size_hints.max_height = icon.Height;
  3481. size_hints.base_width = icon.Width;
  3482. size_hints.base_height = icon.Height;
  3483. XSetWMNormalHints (DisplayHandle, hwnd.whole_window, ref size_hints);
  3484. atoms = new uint [2];
  3485. atoms [0] = 1; // Version 1
  3486. atoms [1] = 0; // We're not mapped
  3487. // This line cost me 3 days...
  3488. XChangeProperty (DisplayHandle, hwnd.whole_window, NetAtoms [(int)NA._XEMBED_INFO], NetAtoms [(int)NA._XEMBED_INFO], 32, PropertyMode.Replace, atoms, 2);
  3489. // Need to pick some reasonable defaults
  3490. tt = new ToolTip ();
  3491. tt.AutomaticDelay = 100;
  3492. tt.InitialDelay = 250;
  3493. tt.ReshowDelay = 250;
  3494. tt.ShowAlways = true;
  3495. if ((tip != null) && (tip != string.Empty)) {
  3496. tt.SetToolTip (Control.FromHandle (handle), tip);
  3497. tt.Active = true;
  3498. } else {
  3499. tt.Active = false;
  3500. }
  3501. // Make sure the window exists
  3502. XSync (DisplayHandle, hwnd.whole_window);
  3503. SendNetClientMessage (SystrayMgrWindow, (IntPtr)NetAtoms [(int)NA._NET_SYSTEM_TRAY_OPCODE], IntPtr.Zero, (IntPtr)SystrayRequest.SYSTEM_TRAY_REQUEST_DOCK, hwnd.whole_window);
  3504. return true;
  3505. }
  3506. tt = null;
  3507. return false;
  3508. }
  3509. internal override bool SystrayChange (IntPtr handle, string tip, Icon icon, ref ToolTip tt)
  3510. {
  3511. Control control;
  3512. control = Control.FromHandle (handle);
  3513. if (control != null && tt != null) {
  3514. tt.SetToolTip (control, tip);
  3515. tt.Active = true;
  3516. return true;
  3517. } else {
  3518. return false;
  3519. }
  3520. }
  3521. internal override void SystrayRemove (IntPtr handle, ref ToolTip tt)
  3522. {
  3523. Hwnd hwnd;
  3524. hwnd = Hwnd.ObjectFromHandle (handle);
  3525. XUnmapWindow (DisplayHandle, hwnd.whole_window);
  3526. SetParent (hwnd.whole_window, FosterParent);
  3527. // The caller can now re-dock it later...
  3528. if (tt != null) {
  3529. tt.Dispose ();
  3530. tt = null;
  3531. }
  3532. }
  3533. internal override bool Text (IntPtr handle, string text)
  3534. {
  3535. lock (XlibLock) {
  3536. gdk_window_set_title (gdk_window_lookup (Hwnd.ObjectFromHandle (handle).whole_window), text);
  3537. }
  3538. return true;
  3539. }
  3540. internal override bool TranslateMessage (ref MSG msg)
  3541. {
  3542. return Keyboard.TranslateMessage (ref msg);
  3543. }
  3544. internal override void UpdateWindow (IntPtr handle)
  3545. {
  3546. XEvent xevent;
  3547. Hwnd hwnd;
  3548. hwnd = Hwnd.ObjectFromHandle (handle);
  3549. if (!hwnd.visible || hwnd.expose_pending) {
  3550. return;
  3551. }
  3552. #if not
  3553. SendMessage(handle, Msg.WM_PAINT, IntPtr.Zero, IntPtr.Zero);
  3554. #else
  3555. xevent = new XEvent ();
  3556. xevent.type = XEventName.Expose;
  3557. xevent.ExposeEvent.display = DisplayHandle;
  3558. xevent.ExposeEvent.window = hwnd.client_window;
  3559. MessageQueue.Enqueue (xevent);
  3560. hwnd.expose_pending = true;
  3561. #endif
  3562. }
  3563. internal static IntPtr NewPixmap (IntPtr gdk_window, int width, int height)
  3564. {
  3565. return gdk_pixmap_new (gdk_window, width, height, 24); // FIXME: instead of 24, get the correct display depth
  3566. }
  3567. internal static void BlitOffscreenPixmap (IntPtr gdk_pixmap, IntPtr dest_drawable, Rectangle area)
  3568. {
  3569. IntPtr gdk_gc = gdk_gc_new (gdk_pixmap);
  3570. gdk_draw_drawable (dest_drawable, gdk_gc, gdk_pixmap, area.X, area.Y, area.X, area.Y, area.Width, area.Height);
  3571. g_object_unref (gdk_gc);
  3572. }
  3573. #endregion // Public Static Methods
  3574. #region Events
  3575. internal override event EventHandler Idle;
  3576. #endregion // Events
  3577. #region X11 Imports
  3578. [DllImport ("libX11", EntryPoint="XSynchronize")]
  3579. internal extern static IntPtr XSynchronize (IntPtr display, bool onoff);
  3580. [DllImport ("libX11", EntryPoint="XCreateWindow")]
  3581. 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);
  3582. [DllImport ("libX11", EntryPoint="XCreateSimpleWindow")]
  3583. internal extern static IntPtr XCreateSimpleWindow (IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, int border, int background);
  3584. [DllImport ("libX11", EntryPoint="XMapWindow")]
  3585. internal extern static int XMapWindow (IntPtr display, IntPtr window);
  3586. [DllImport ("libX11", EntryPoint="XUnmapWindow")]
  3587. internal extern static int XUnmapWindow (IntPtr display, IntPtr window);
  3588. [DllImport ("libX11", EntryPoint="XMapSubwindows")]
  3589. internal extern static int XMapSubindows (IntPtr display, IntPtr window);
  3590. [DllImport ("libX11", EntryPoint="XUnmapSubwindows")]
  3591. internal extern static int XUnmapSubwindows (IntPtr display, IntPtr window);
  3592. [DllImport ("libX11", EntryPoint="XRootWindow")]
  3593. internal extern static IntPtr XRootWindow (IntPtr display, int screen_number);
  3594. [DllImport ("libX11", EntryPoint="XNextEvent")]
  3595. internal extern static IntPtr XNextEvent (IntPtr display, ref XEvent xevent);
  3596. [DllImport ("libX11")]
  3597. internal extern static int XConnectionNumber (IntPtr diplay);
  3598. [DllImport ("libX11")]
  3599. internal extern static int XPending (IntPtr diplay);
  3600. [DllImport ("libX11")]
  3601. internal extern static bool XCheckWindowEvent (IntPtr display, IntPtr window, EventMask mask, ref XEvent xevent);
  3602. [DllImport ("libX11")]
  3603. internal extern static bool XCheckMaskEvent (IntPtr display, EventMask mask, ref XEvent xevent);
  3604. [DllImport ("libX11", EntryPoint="XSelectInput")]
  3605. internal extern static IntPtr XSelectInput (IntPtr display, IntPtr window, EventMask mask);
  3606. [DllImport ("libX11", EntryPoint="XReparentWindow")]
  3607. internal extern static int XReparentWindow (IntPtr display, IntPtr window, IntPtr parent, int x, int y);
  3608. [DllImport ("libX11", EntryPoint="XMoveResizeWindow")]
  3609. internal extern static int XMoveResizeWindow (IntPtr display, IntPtr window, int x, int y, int width, int height);
  3610. [DllImport ("libX11", EntryPoint="XResizeWindow")]
  3611. internal extern static int XResizeWindow (IntPtr display, IntPtr window, int width, int height);
  3612. [DllImport ("libX11", EntryPoint="XGetWindowAttributes")]
  3613. internal extern static int XGetWindowAttributes (IntPtr display, IntPtr window, ref XWindowAttributes attributes);
  3614. [DllImport ("libX11", EntryPoint="XFlush")]
  3615. internal extern static int XFlush (IntPtr display);
  3616. [DllImport ("libX11", EntryPoint="XSetWMName")]
  3617. internal extern static int XSetWMName (IntPtr display, IntPtr window, ref XTextProperty text_prop);
  3618. [DllImport ("libX11", EntryPoint="XStoreName")]
  3619. internal extern static int XStoreName (IntPtr display, IntPtr window, string window_name);
  3620. [DllImport ("libX11", EntryPoint="XFetchName")]
  3621. internal extern static int XFetchName (IntPtr display, IntPtr window, ref IntPtr window_name);
  3622. [DllImport ("libX11", EntryPoint="XSendEvent")]
  3623. internal extern static int XSendEvent (IntPtr display, IntPtr window, bool propagate, EventMask event_mask, ref XEvent send_event);
  3624. [DllImport ("libX11", EntryPoint="XQueryTree")]
  3625. 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);
  3626. [DllImport ("libX11", EntryPoint="XFree")]
  3627. internal extern static int XFree (IntPtr data);
  3628. [DllImport ("libX11", EntryPoint="XRaiseWindow")]
  3629. internal extern static int XRaiseWindow (IntPtr display, IntPtr window);
  3630. [DllImport ("libX11", EntryPoint="XLowerWindow")]
  3631. internal extern static uint XLowerWindow (IntPtr display, IntPtr window);
  3632. [DllImport ("libX11", EntryPoint="XConfigureWindow")]
  3633. internal extern static uint XConfigureWindow (IntPtr display, IntPtr window, ChangeWindowFlags value_mask, ref XWindowChanges values);
  3634. [DllImport ("libX11", EntryPoint="XInternAtom")]
  3635. internal extern static int XInternAtom (IntPtr display, string atom_name, bool only_if_exists);
  3636. [DllImport ("libX11", EntryPoint="XSetWMProtocols")]
  3637. internal extern static int XSetWMProtocols (IntPtr display, IntPtr window, uint[] protocols, int count);
  3638. [DllImport ("libX11", EntryPoint="XGrabPointer")]
  3639. 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);
  3640. [DllImport ("libX11", EntryPoint="XUngrabPointer")]
  3641. internal extern static int XUngrabPointer (IntPtr display, uint timestamp);
  3642. [DllImport ("libX11", EntryPoint="XQueryPointer")]
  3643. 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);
  3644. [DllImport ("libX11", EntryPoint="XTranslateCoordinates")]
  3645. 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);
  3646. [DllImport ("libX11", EntryPoint="XWarpPointer")]
  3647. 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);
  3648. [DllImport ("libX11", EntryPoint="XClearWindow")]
  3649. internal extern static int XClearWindow (IntPtr display, IntPtr window);
  3650. [DllImport ("libX11", EntryPoint="XClearArea")]
  3651. internal extern static int XClearArea (IntPtr display, IntPtr window, int x, int y, int width, int height, bool exposures);
  3652. // Colormaps
  3653. [DllImport ("libX11", EntryPoint="XDefaultScreenOfDisplay")]
  3654. internal extern static IntPtr XDefaultScreenOfDisplay (IntPtr display);
  3655. [DllImport ("libX11", EntryPoint="XScreenNumberOfScreen")]
  3656. internal extern static int XScreenNumberOfScreen (IntPtr display, IntPtr Screen);
  3657. [DllImport ("libX11", EntryPoint="XDefaultVisual")]
  3658. internal extern static IntPtr XDefaultVisual (IntPtr display, int screen_number);
  3659. [DllImport ("libX11", EntryPoint="XDefaultDepth")]
  3660. internal extern static uint XDefaultDepth (IntPtr display, int screen_number);
  3661. [DllImport ("libX11", EntryPoint="XDefaultColormap")]
  3662. internal extern static IntPtr XDefaultColormap (IntPtr display, int screen_number);
  3663. [DllImport ("libX11", EntryPoint="XLookupColor")]
  3664. internal extern static int XLookupColor (IntPtr display, IntPtr Colormap, string Coloranem, ref XColor exact_def_color, ref XColor screen_def_color);
  3665. [DllImport ("libX11", EntryPoint="XAllocColor")]
  3666. internal extern static int XAllocColor (IntPtr display, IntPtr Colormap, ref XColor colorcell_def);
  3667. [DllImport ("libX11", EntryPoint="XSetTransientForHint")]
  3668. internal extern static int XSetTransientForHint (IntPtr display, IntPtr window, IntPtr prop_window);
  3669. [DllImport ("libX11", EntryPoint="XChangeProperty")]
  3670. internal extern static int XChangeProperty (IntPtr display, IntPtr window, int property, int type, int format, PropertyMode mode, ref MotifWmHints data, int nelements);
  3671. [DllImport ("libX11", EntryPoint="XChangeProperty")]
  3672. internal extern static int XChangeProperty (IntPtr display, IntPtr window, int property, Atom format, int type, PropertyMode mode, uint[] atoms, int nelements);
  3673. [DllImport ("libX11", EntryPoint="XChangeProperty")]
  3674. internal extern static int XChangeProperty (IntPtr display, IntPtr window, int property, Atom format, int type, PropertyMode mode, ref uint value, int nelements);
  3675. [DllImport ("libX11", EntryPoint="XChangeProperty")]
  3676. internal extern static int XChangeProperty (IntPtr display, IntPtr window, int property, int format, int type, PropertyMode mode, uint[] atoms, int nelements);
  3677. [DllImport ("libX11", EntryPoint="XChangeProperty")]
  3678. internal extern static int XChangeProperty (IntPtr display, IntPtr window, int property, int format, int type, PropertyMode mode, IntPtr atoms, int nelements);
  3679. [DllImport ("libX11", EntryPoint="XChangeProperty")]
  3680. internal extern static int XChangeProperty (IntPtr display, IntPtr window, int property, Atom format, int type, PropertyMode mode, IntPtr atoms, int nelements);
  3681. [DllImport ("libX11", EntryPoint="XChangeProperty", CharSet=CharSet.Ansi)]
  3682. internal extern static int XChangeProperty (IntPtr display, IntPtr window, int property, int type, int format, PropertyMode mode, string text, int text_length);
  3683. [DllImport ("libX11", EntryPoint="XDeleteProperty")]
  3684. internal extern static int XDeleteProperty (IntPtr display, IntPtr window, int property);
  3685. // Drawing
  3686. [DllImport ("libX11", EntryPoint="XCreateGC")]
  3687. internal extern static IntPtr XCreateGC (IntPtr display, IntPtr window, GCFunction valuemask, ref XGCValues values);
  3688. [DllImport ("libX11", EntryPoint="XFreeGC")]
  3689. internal extern static int XFreeGC (IntPtr display, IntPtr gc);
  3690. [DllImport ("libX11", EntryPoint="XSetFunction")]
  3691. internal extern static int XSetFunction (IntPtr display, IntPtr gc, GXFunction function);
  3692. [DllImport ("libX11", EntryPoint="XDrawLine")]
  3693. internal extern static int XDrawLine (IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2);
  3694. [DllImport ("libX11", EntryPoint="XDrawRectangle")]
  3695. internal extern static int XDrawRectangle (IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
  3696. [DllImport ("libX11", EntryPoint="XSetWindowBackground")]
  3697. internal extern static int XSetWindowBackground (IntPtr display, IntPtr window, IntPtr background);
  3698. [DllImport ("libX11", EntryPoint="XCopyArea")]
  3699. 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);
  3700. [DllImport ("libX11", EntryPoint="XGetAtomName")]
  3701. internal extern static string XGetAtomName (IntPtr display, int atom);
  3702. [DllImport ("libX11", EntryPoint="XGetWindowProperty")]
  3703. 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);
  3704. [DllImport ("libX11", EntryPoint="XSetInputFocus")]
  3705. internal extern static int XSetInputFocus (IntPtr display, IntPtr window, RevertTo revert_to, IntPtr time);
  3706. [DllImport ("libX11", EntryPoint="XIconifyWindow")]
  3707. internal extern static int XIconifyWindow (IntPtr display, IntPtr window, int screen_number);
  3708. [DllImport ("libX11", EntryPoint="XDefineCursor")]
  3709. internal extern static int XDefineCursor (IntPtr display, IntPtr window, IntPtr cursor);
  3710. [DllImport ("libX11", EntryPoint="XUndefineCursor")]
  3711. internal extern static int XUndefineCursor (IntPtr display, IntPtr window);
  3712. [DllImport ("libX11", EntryPoint="XFreeCursor")]
  3713. internal extern static int XFreeCursor (IntPtr display, IntPtr cursor);
  3714. [DllImport ("libX11", EntryPoint="XCreateFontCursor")]
  3715. internal extern static IntPtr XCreateFontCursor (IntPtr display, CursorFontShape shape);
  3716. [DllImport ("libX11", EntryPoint="XCreatePixmapCursor")]
  3717. 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);
  3718. [DllImport ("libX11", EntryPoint="XCreatePixmapFromBitmapData")]
  3719. internal extern static IntPtr XCreatePixmapFromBitmapData (IntPtr display, IntPtr drawable, byte[] data, int width, int height, IntPtr fg, IntPtr bg, int depth);
  3720. [DllImport ("libX11", EntryPoint="XFreePixmap")]
  3721. internal extern static IntPtr XFreePixmap (IntPtr display, IntPtr pixmap);
  3722. [DllImport ("libX11", EntryPoint="XWhitePixel")]
  3723. internal extern static IntPtr XWhitePixel (IntPtr display, int screen_no);
  3724. [DllImport ("libX11", EntryPoint="XBlackPixel")]
  3725. internal extern static IntPtr XBlackPixel (IntPtr display, int screen_no);
  3726. [DllImport ("libX11", EntryPoint="XGrabServer")]
  3727. internal extern static void XGrabServer (IntPtr display);
  3728. [DllImport ("libX11", EntryPoint="XUngrabServer")]
  3729. internal extern static void XUngrabServer (IntPtr display);
  3730. [DllImport ("libX11", EntryPoint="XSetWMNormalHints")]
  3731. internal extern static void XSetWMNormalHints (IntPtr display, IntPtr window, ref XSizeHints hints);
  3732. [DllImport ("libX11", EntryPoint="XSetZoomHints")]
  3733. internal extern static void XSetZoomHints (IntPtr display, IntPtr window, ref XSizeHints hints);
  3734. [DllImport ("libX11", EntryPoint="XSetWMHints")]
  3735. internal extern static void XSetWMHints (IntPtr display, IntPtr window, ref XWMHints wmhints);
  3736. [DllImport ("libX11", EntryPoint="XSync")]
  3737. internal extern static void XSync (IntPtr display, IntPtr window);
  3738. [DllImport ("libX11", EntryPoint="XGetIconSizes")]
  3739. internal extern static int XGetIconSizes (IntPtr display, IntPtr window, out IntPtr size_list, out int count);
  3740. [DllImport ("libX11", EntryPoint="XSetErrorHandler")]
  3741. internal extern static IntPtr XSetErrorHandler (XErrorHandler error_handler);
  3742. [DllImport ("libX11", EntryPoint="XGetErrorText")]
  3743. internal extern static IntPtr XGetErrorText (IntPtr display, byte code, StringBuilder buffer, int length);
  3744. [DllImport ("libX11", EntryPoint="XInitThreads")]
  3745. internal extern static int XInitThreads ();
  3746. [DllImport ("libX11", EntryPoint="XConvertSelection")]
  3747. internal extern static int XConvertSelection (IntPtr display, int selection, int target, int property, IntPtr requestor, IntPtr time);
  3748. [DllImport ("libX11", EntryPoint="XGetSelectionOwner")]
  3749. internal extern static IntPtr XGetSelectionOwner (IntPtr display, int selection);
  3750. [DllImport ("libX11", EntryPoint="XSetSelectionOwner")]
  3751. internal extern static int XSetSelectionOwner (IntPtr display, int selection, IntPtr owner, IntPtr time);
  3752. [DllImport ("libX11", EntryPoint="XSetPlaneMask")]
  3753. internal extern static int XSetPlaneMask (IntPtr display, IntPtr gc, uint mask);
  3754. [DllImport ("libX11", EntryPoint="XSetForeground")]
  3755. internal extern static int XSetForeground (IntPtr display, IntPtr gc, uint foreground);
  3756. [DllImport ("libX11", EntryPoint="XSetBackground")]
  3757. internal extern static int XSetBackground (IntPtr display, IntPtr gc, uint background);
  3758. #endregion
  3759. #region gdk imports
  3760. [DllImport("libgdk-x11-2.0.so")]
  3761. static extern bool gdk_init_check (IntPtr argc, IntPtr argv);
  3762. [DllImport("libgdk-x11-2.0.so")]
  3763. internal static extern IntPtr gdk_x11_display_get_xdisplay (IntPtr display);
  3764. [DllImport("libgdk-x11-2.0.so")]
  3765. internal static extern IntPtr gdk_display_get_default ();
  3766. [DllImport("libgdk-x11-2.0.so")]
  3767. static extern IntPtr gdk_pixmap_new (IntPtr drawable, int width, int height, int depth);
  3768. [DllImport("libgdk-x11-2.0.so")]
  3769. static extern IntPtr gdk_x11_drawable_get_xid (IntPtr gdkdrawable);
  3770. [DllImport("libgdk-x11-2.0.so")]
  3771. 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);
  3772. [DllImport("libgdk-x11-2.0.so")]
  3773. static extern IntPtr gdk_gc_new (IntPtr drawable);
  3774. [DllImport("libgdk-x11-2.0.so")]
  3775. static extern IntPtr gdk_window_foreign_new (IntPtr anid);
  3776. [DllImport("libgdk-x11-2.0.so")]
  3777. static extern IntPtr gdk_x11_lookup_xdisplay (IntPtr xdisplay);
  3778. [DllImport("libgdk-x11-2.0.so")]
  3779. static extern void gdk_display_close (IntPtr display);
  3780. [DllImport("libgdk-x11-2.0.so")]
  3781. static extern void gdk_display_beep (IntPtr display);
  3782. [DllImport("libgdk-x11-2.0.so")]
  3783. static extern void gdk_display_sync (IntPtr display);
  3784. [DllImport("libgdk-x11-2.0.so")]
  3785. static extern IntPtr gdk_get_default_root_window ();
  3786. [DllImport("libgdk-x11-2.0.so")]
  3787. static extern IntPtr gdk_colormap_get_system ();
  3788. [DllImport("libgdk-x11-2.0.so")]
  3789. static extern IntPtr gdk_x11_colormap_get_xcolormap (IntPtr gdk_colormap);
  3790. [DllImport("libgdk-x11-2.0.so")]
  3791. static extern void gdk_window_destroy (IntPtr gdk_window);
  3792. [DllImport("libgdk-x11-2.0.so")]
  3793. static extern void gdk_x11_grab_server ();
  3794. [DllImport("libgdk-x11-2.0.so")]
  3795. static extern void gdk_x11_ungrab_server ();
  3796. [DllImport("libgdk-x11-2.0.so")]
  3797. static extern void gdk_display_flush (IntPtr gdk_display);
  3798. [DllImport("libgdk-x11-2.0.so")]
  3799. static extern void gdk_window_iconify (IntPtr gdk_window);
  3800. [DllImport("libgdk-x11-2.0.so")]
  3801. static extern void gdk_window_deiconify (IntPtr gdk_window);
  3802. [DllImport("libgdk-x11-2.0.so")]
  3803. static extern void gdk_window_set_decorations (IntPtr gdk_window, int decorations);
  3804. [DllImport("libgdk-x11-2.0.so")]
  3805. static extern IntPtr gdk_screen_get_default ();
  3806. [DllImport("libgdk-x11-2.0.so")]
  3807. static extern int gdk_screen_get_number (IntPtr gdk_screen);
  3808. [DllImport("libgdk-x11-2.0.so")]
  3809. static extern IntPtr gdk_window_lookup (IntPtr anid);
  3810. [DllImport("libgdk-x11-2.0.so")]
  3811. static extern IntPtr gdk_window_new (IntPtr gdk_parent, ref GdkWindowAttr gdk_window_attributes, int attributes_mask);
  3812. [DllImport("libgdk-x11-2.0.so")]
  3813. static extern void gdk_window_set_events (IntPtr gdk_window, int event_mask);
  3814. [DllImport("libgdk-x11-2.0.so")]
  3815. static extern void gdk_window_show (IntPtr window);
  3816. [DllImport("libgdk-x11-2.0.so")]
  3817. static extern void gdk_window_set_title (IntPtr gdk_window, string title);
  3818. [DllImport("libgdk-x11-2.0.so")]
  3819. static extern int gdk_window_get_origin (IntPtr gdk_window, out int x, out int y);
  3820. [DllImport("libgdk-x11-2.0.so")]
  3821. 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);
  3822. [DllImport("libgdk-x11-2.0.so")]
  3823. 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);
  3824. [DllImport("libgdk-x11-2.0.so")]
  3825. static extern IntPtr gdk_window_get_parent (IntPtr gdk_window);
  3826. [DllImport("libgdk-x11-2.0.so")]
  3827. static extern void gdk_display_get_maximal_cursor_size (IntPtr gdk_display, out uint width, out uint height);
  3828. [DllImport("libgdk-x11-2.0.so")]
  3829. static extern int gdk_visual_get_best_depth ();
  3830. #endregion
  3831. #region gobject imports
  3832. [DllImport("libglib-2.0.so")]
  3833. static extern void g_free (IntPtr mem);
  3834. [DllImport("libgobject-2.0.so")]
  3835. static extern void g_object_unref (IntPtr nativeObject);
  3836. #endregion
  3837. }
  3838. }