PageRenderTime 89ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 2ms

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

https://bitbucket.org/danipen/mono
C# | 7588 lines | 5716 code | 1347 blank | 525 comment | 1173 complexity | a5b31050b832856e57a30cc5ca58b9dc 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. //
  25. //
  26. // NOTE:
  27. // This driver understands the following environment variables: (Set the var to enable feature)
  28. //
  29. // MONO_XEXCEPTIONS = throw an exception when a X11 error is encountered;
  30. // by default a message is displayed but execution continues
  31. //
  32. // MONO_XSYNC = perform all X11 commands synchronous; this is slower but
  33. // helps in debugging errors
  34. //
  35. // NOT COMPLETE
  36. // define to log Window handles and relationships to stdout
  37. #undef DriverDebug
  38. // Extra detailed debug
  39. #undef DriverDebugExtra
  40. #undef DriverDebugParent
  41. #undef DriverDebugCreate
  42. #undef DriverDebugDestroy
  43. #undef DriverDebugThreads
  44. #undef DriverDebugXEmbed
  45. //#define TRACE
  46. //#define DEBUG
  47. using System;
  48. using System.ComponentModel;
  49. using System.Collections;
  50. using System.Diagnostics;
  51. using System.Drawing;
  52. using System.Drawing.Drawing2D;
  53. using System.Drawing.Imaging;
  54. using System.IO;
  55. using System.Net;
  56. using System.Net.Sockets;
  57. using System.Reflection;
  58. using System.Runtime.InteropServices;
  59. using System.Runtime.Serialization;
  60. using System.Runtime.Serialization.Formatters.Binary;
  61. using System.Text;
  62. using System.Threading;
  63. // Only do the poll when building with mono for now
  64. #if __MonoCS__
  65. using Mono.Unix.Native;
  66. #endif
  67. /// X11 Version
  68. namespace System.Windows.Forms {
  69. internal class XplatUIX11 : XplatUIDriver {
  70. #region Local Variables
  71. // General
  72. static volatile XplatUIX11 Instance;
  73. static int RefCount;
  74. static object XlibLock; // Our locking object
  75. static bool themes_enabled;
  76. // General X11
  77. static IntPtr DisplayHandle; // X11 handle to display
  78. static int ScreenNo; // Screen number used
  79. static IntPtr DefaultColormap; // Colormap for screen
  80. static IntPtr CustomVisual; // Visual for window creation
  81. static IntPtr CustomColormap; // Colormap for window creation
  82. static IntPtr RootWindow; // Handle of the root window for the screen/display
  83. static IntPtr FosterParent; // Container to hold child windows until their parent exists
  84. static XErrorHandler ErrorHandler; // Error handler delegate
  85. static bool ErrorExceptions; // Throw exceptions on X errors
  86. int render_major_opcode;
  87. int render_first_event;
  88. int render_first_error;
  89. // Clipboard
  90. static IntPtr ClipMagic;
  91. static ClipboardData Clipboard; // Our clipboard
  92. // Communication
  93. static IntPtr PostAtom; // PostMessage atom
  94. static IntPtr AsyncAtom; // Support for async messages
  95. // Message Loop
  96. static Hashtable MessageQueues; // Holds our thread-specific XEventQueues
  97. static ArrayList unattached_timer_list; // holds timers that are enabled but not attached to a window.
  98. #if __MonoCS__ //
  99. static Pollfd[] pollfds; // For watching the X11 socket
  100. static bool wake_waiting;
  101. static object wake_waiting_lock = new object ();
  102. #endif //
  103. static X11Keyboard Keyboard; //
  104. static X11Dnd Dnd;
  105. static Socket listen; //
  106. static Socket wake; //
  107. static Socket wake_receive; //
  108. static byte[] network_buffer; //
  109. static bool detectable_key_auto_repeat;
  110. // Focus tracking
  111. static IntPtr ActiveWindow; // Handle of the active window
  112. static IntPtr FocusWindow; // Handle of the window with keyboard focus (if any)
  113. // Modality support
  114. static Stack ModalWindows; // Stack of our modal windows
  115. // Systray
  116. static IntPtr SystrayMgrWindow; // Handle of the Systray Manager window
  117. // Cursors
  118. static IntPtr LastCursorWindow; // The last window we set the cursor on
  119. static IntPtr LastCursorHandle; // The handle that was last set on LastCursorWindow
  120. static IntPtr OverrideCursorHandle; // The cursor that is set to override any other cursors
  121. // Caret
  122. static CaretStruct Caret; //
  123. // Last window containing the pointer
  124. static IntPtr LastPointerWindow; // The last window containing the pointer
  125. // Our atoms
  126. static IntPtr WM_PROTOCOLS;
  127. static IntPtr WM_DELETE_WINDOW;
  128. static IntPtr WM_TAKE_FOCUS;
  129. //static IntPtr _NET_SUPPORTED;
  130. //static IntPtr _NET_CLIENT_LIST;
  131. //static IntPtr _NET_NUMBER_OF_DESKTOPS;
  132. static IntPtr _NET_DESKTOP_GEOMETRY;
  133. //static IntPtr _NET_DESKTOP_VIEWPORT;
  134. static IntPtr _NET_CURRENT_DESKTOP;
  135. //static IntPtr _NET_DESKTOP_NAMES;
  136. static IntPtr _NET_ACTIVE_WINDOW;
  137. static IntPtr _NET_WORKAREA;
  138. //static IntPtr _NET_SUPPORTING_WM_CHECK;
  139. //static IntPtr _NET_VIRTUAL_ROOTS;
  140. //static IntPtr _NET_DESKTOP_LAYOUT;
  141. //static IntPtr _NET_SHOWING_DESKTOP;
  142. //static IntPtr _NET_CLOSE_WINDOW;
  143. //static IntPtr _NET_MOVERESIZE_WINDOW;
  144. static IntPtr _NET_WM_MOVERESIZE;
  145. //static IntPtr _NET_RESTACK_WINDOW;
  146. //static IntPtr _NET_REQUEST_FRAME_EXTENTS;
  147. static IntPtr _NET_WM_NAME;
  148. //static IntPtr _NET_WM_VISIBLE_NAME;
  149. //static IntPtr _NET_WM_ICON_NAME;
  150. //static IntPtr _NET_WM_VISIBLE_ICON_NAME;
  151. //static IntPtr _NET_WM_DESKTOP;
  152. static IntPtr _NET_WM_WINDOW_TYPE;
  153. static IntPtr _NET_WM_STATE;
  154. //static IntPtr _NET_WM_ALLOWED_ACTIONS;
  155. //static IntPtr _NET_WM_STRUT;
  156. //static IntPtr _NET_WM_STRUT_PARTIAL;
  157. //static IntPtr _NET_WM_ICON_GEOMETRY;
  158. static IntPtr _NET_WM_ICON;
  159. //static IntPtr _NET_WM_PID;
  160. //static IntPtr _NET_WM_HANDLED_ICONS;
  161. static IntPtr _NET_WM_USER_TIME;
  162. static IntPtr _NET_FRAME_EXTENTS;
  163. //static IntPtr _NET_WM_PING;
  164. //static IntPtr _NET_WM_SYNC_REQUEST;
  165. static IntPtr _NET_SYSTEM_TRAY_S;
  166. //static IntPtr _NET_SYSTEM_TRAY_ORIENTATION;
  167. static IntPtr _NET_SYSTEM_TRAY_OPCODE;
  168. static IntPtr _NET_WM_STATE_MAXIMIZED_HORZ;
  169. static IntPtr _NET_WM_STATE_MAXIMIZED_VERT;
  170. static IntPtr _XEMBED;
  171. static IntPtr _XEMBED_INFO;
  172. static IntPtr _MOTIF_WM_HINTS;
  173. static IntPtr _NET_WM_STATE_SKIP_TASKBAR;
  174. static IntPtr _NET_WM_STATE_ABOVE;
  175. static IntPtr _NET_WM_STATE_MODAL;
  176. static IntPtr _NET_WM_STATE_HIDDEN;
  177. static IntPtr _NET_WM_CONTEXT_HELP;
  178. static IntPtr _NET_WM_WINDOW_OPACITY;
  179. //static IntPtr _NET_WM_WINDOW_TYPE_DESKTOP;
  180. //static IntPtr _NET_WM_WINDOW_TYPE_DOCK;
  181. //static IntPtr _NET_WM_WINDOW_TYPE_TOOLBAR;
  182. //static IntPtr _NET_WM_WINDOW_TYPE_MENU;
  183. static IntPtr _NET_WM_WINDOW_TYPE_UTILITY;
  184. //static IntPtr _NET_WM_WINDOW_TYPE_SPLASH;
  185. // static IntPtr _NET_WM_WINDOW_TYPE_DIALOG;
  186. static IntPtr _NET_WM_WINDOW_TYPE_NORMAL;
  187. static IntPtr CLIPBOARD;
  188. static IntPtr PRIMARY;
  189. //static IntPtr DIB;
  190. static IntPtr OEMTEXT;
  191. static IntPtr UTF8_STRING;
  192. static IntPtr UTF16_STRING;
  193. static IntPtr RICHTEXTFORMAT;
  194. static IntPtr TARGETS;
  195. // mouse hover message generation
  196. static HoverStruct HoverState; //
  197. // double click message generation
  198. static ClickStruct ClickPending; //
  199. // Support for mouse grab
  200. static GrabStruct Grab; //
  201. // State
  202. Point mouse_position; // Last position of mouse, in screen coords
  203. internal static MouseButtons MouseState; // Last state of mouse buttons
  204. internal static bool in_doevents;
  205. // 'Constants'
  206. static int DoubleClickInterval; // msec; max interval between clicks to count as double click
  207. const EventMask SelectInputMask = (EventMask.ButtonPressMask |
  208. EventMask.ButtonReleaseMask |
  209. EventMask.KeyPressMask |
  210. EventMask.KeyReleaseMask |
  211. EventMask.EnterWindowMask |
  212. EventMask.LeaveWindowMask |
  213. EventMask.ExposureMask |
  214. EventMask.FocusChangeMask |
  215. EventMask.PointerMotionMask |
  216. EventMask.PointerMotionHintMask |
  217. EventMask.SubstructureNotifyMask);
  218. static readonly object lockobj = new object ();
  219. // messages WaitForHwndMwssage is waiting on
  220. static Hashtable messageHold;
  221. #endregion // Local Variables
  222. #region Constructors
  223. XplatUIX11()
  224. {
  225. // Handle singleton stuff first
  226. RefCount = 0;
  227. in_doevents = false;
  228. // Now regular initialization
  229. XlibLock = new object ();
  230. X11Keyboard.XlibLock = XlibLock;
  231. MessageQueues = Hashtable.Synchronized (new Hashtable(7));
  232. unattached_timer_list = ArrayList.Synchronized (new ArrayList (3));
  233. messageHold = Hashtable.Synchronized (new Hashtable(3));
  234. Clipboard = new ClipboardData ();
  235. XInitThreads();
  236. ErrorExceptions = false;
  237. // X11 Initialization
  238. SetDisplay(XOpenDisplay(IntPtr.Zero));
  239. X11DesktopColors.Initialize();
  240. // Disable keyboard autorepeat
  241. try {
  242. XkbSetDetectableAutoRepeat (DisplayHandle, true, IntPtr.Zero);
  243. detectable_key_auto_repeat = true;
  244. } catch {
  245. Console.Error.WriteLine ("Could not disable keyboard auto repeat, will attempt to disable manually.");
  246. detectable_key_auto_repeat = false;
  247. }
  248. // Handle any upcoming errors; we re-set it here, X11DesktopColor stuff might have stolen it (gtk does)
  249. ErrorHandler = new XErrorHandler(HandleError);
  250. XSetErrorHandler(ErrorHandler);
  251. }
  252. ~XplatUIX11() {
  253. // Remove our display handle from S.D
  254. Graphics.FromHdcInternal (IntPtr.Zero);
  255. }
  256. #endregion // Constructors
  257. #region Singleton Specific Code
  258. public static XplatUIX11 GetInstance() {
  259. lock (lockobj) {
  260. if (Instance == null) {
  261. Instance=new XplatUIX11();
  262. }
  263. RefCount++;
  264. }
  265. return Instance;
  266. }
  267. public int Reference {
  268. get {
  269. return RefCount;
  270. }
  271. }
  272. #endregion
  273. #region Internal Properties
  274. internal static IntPtr Display {
  275. get {
  276. return DisplayHandle;
  277. }
  278. set {
  279. XplatUIX11.GetInstance().SetDisplay(value);
  280. }
  281. }
  282. internal static int Screen {
  283. get {
  284. return ScreenNo;
  285. }
  286. set {
  287. ScreenNo = value;
  288. }
  289. }
  290. internal static IntPtr RootWindowHandle {
  291. get {
  292. return RootWindow;
  293. }
  294. set {
  295. RootWindow = value;
  296. }
  297. }
  298. internal static IntPtr Visual {
  299. get {
  300. return CustomVisual;
  301. }
  302. set {
  303. CustomVisual = value;
  304. }
  305. }
  306. internal static IntPtr ColorMap {
  307. get {
  308. return CustomColormap;
  309. }
  310. set {
  311. CustomColormap = value;
  312. }
  313. }
  314. #if DEBUG_shana
  315. internal static IntPtr DefaultColorMap {
  316. get {
  317. return DefaultColormap;
  318. }
  319. }
  320. #endif
  321. #endregion
  322. #region XExceptionClass
  323. internal class XException : ApplicationException {
  324. IntPtr Display;
  325. IntPtr ResourceID;
  326. IntPtr Serial;
  327. XRequest RequestCode;
  328. byte ErrorCode;
  329. byte MinorCode;
  330. public XException(IntPtr Display, IntPtr ResourceID, IntPtr Serial, byte ErrorCode, XRequest RequestCode, byte MinorCode) {
  331. this.Display = Display;
  332. this.ResourceID = ResourceID;
  333. this.Serial = Serial;
  334. this.RequestCode = RequestCode;
  335. this.ErrorCode = ErrorCode;
  336. this.MinorCode = MinorCode;
  337. }
  338. public override string Message {
  339. get {
  340. return GetMessage(Display, ResourceID, Serial, ErrorCode, RequestCode, MinorCode);
  341. }
  342. }
  343. public static string GetMessage(IntPtr Display, IntPtr ResourceID, IntPtr Serial, byte ErrorCode, XRequest RequestCode, byte MinorCode) {
  344. StringBuilder sb;
  345. string x_error_text;
  346. string error;
  347. string hwnd_text;
  348. string control_text;
  349. Hwnd hwnd;
  350. Control c;
  351. sb = new StringBuilder(160);
  352. XGetErrorText(Display, ErrorCode, sb, sb.Capacity);
  353. x_error_text = sb.ToString();
  354. hwnd = Hwnd.ObjectFromHandle(ResourceID);
  355. if (hwnd != null) {
  356. hwnd_text = hwnd.ToString();
  357. c = Control.FromHandle(hwnd.Handle);
  358. if (c != null) {
  359. control_text = c.ToString();
  360. } else {
  361. control_text = String.Format("<handle {0:X} non-existant>", hwnd.Handle.ToInt32());
  362. }
  363. } else {
  364. hwnd_text = "<null>";
  365. control_text = "<null>";
  366. }
  367. error = String.Format("\n Error: {0}\n Request: {1:D} ({2})\n Resource ID: 0x{3:X}\n Serial: {4}\n Hwnd: {5}\n Control: {6}", x_error_text, RequestCode, MinorCode, ResourceID.ToInt32(), Serial, hwnd_text, control_text);
  368. return error;
  369. }
  370. }
  371. #endregion // XExceptionClass
  372. #region Internal Methods
  373. internal void SetDisplay(IntPtr display_handle)
  374. {
  375. if (display_handle != IntPtr.Zero) {
  376. Hwnd hwnd;
  377. if ((DisplayHandle != IntPtr.Zero) && (FosterParent != IntPtr.Zero)) {
  378. hwnd = Hwnd.ObjectFromHandle(FosterParent);
  379. XDestroyWindow(DisplayHandle, FosterParent);
  380. hwnd.Dispose();
  381. }
  382. if (DisplayHandle != IntPtr.Zero) {
  383. XCloseDisplay(DisplayHandle);
  384. }
  385. DisplayHandle=display_handle;
  386. // We need to tell System.Drawing our DisplayHandle. FromHdcInternal has
  387. // been hacked to do this for us.
  388. Graphics.FromHdcInternal (DisplayHandle);
  389. // query for the render extension so
  390. // we can ignore the spurious
  391. // BadPicture errors that are
  392. // generated by cairo/render.
  393. XQueryExtension (DisplayHandle, "RENDER",
  394. ref render_major_opcode, ref render_first_event, ref render_first_error);
  395. // Debugging support
  396. if (Environment.GetEnvironmentVariable ("MONO_XSYNC") != null) {
  397. XSynchronize(DisplayHandle, true);
  398. }
  399. if (Environment.GetEnvironmentVariable ("MONO_XEXCEPTIONS") != null) {
  400. ErrorExceptions = true;
  401. }
  402. // Generic X11 setup
  403. ScreenNo = XDefaultScreen(DisplayHandle);
  404. RootWindow = XRootWindow(DisplayHandle, ScreenNo);
  405. DefaultColormap = XDefaultColormap(DisplayHandle, ScreenNo);
  406. // Create the foster parent
  407. // it is important that border_width is kept in synch with the other XCreateWindow calls
  408. FosterParent=XCreateSimpleWindow(DisplayHandle, RootWindow, 0, 0, 1, 1, 0, UIntPtr.Zero, UIntPtr.Zero);
  409. if (FosterParent==IntPtr.Zero) {
  410. Console.WriteLine("XplatUIX11 Constructor failed to create FosterParent");
  411. }
  412. DebugHelper.WriteLine ("FosterParent created 0x{0:x}", FosterParent.ToInt32());
  413. hwnd = new Hwnd();
  414. hwnd.Queue = ThreadQueue(Thread.CurrentThread);
  415. hwnd.WholeWindow = FosterParent;
  416. hwnd.ClientWindow = FosterParent;
  417. // Create a HWND for RootWIndow as well, so our queue doesn't eat the events
  418. hwnd = new Hwnd();
  419. hwnd.Queue = ThreadQueue(Thread.CurrentThread);
  420. hwnd.whole_window = RootWindow;
  421. hwnd.ClientWindow = RootWindow;
  422. // For sleeping on the X11 socket
  423. listen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
  424. IPEndPoint ep = new IPEndPoint(IPAddress.Loopback, 0);
  425. listen.Bind(ep);
  426. listen.Listen(1);
  427. // To wake up when a timer is ready
  428. network_buffer = new byte[10];
  429. wake = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
  430. wake.Connect(listen.LocalEndPoint);
  431. // Make this non-blocking, so it doesn't
  432. // deadlock if too many wakes are sent
  433. // before the wake_receive end is polled
  434. wake.Blocking = false;
  435. wake_receive = listen.Accept();
  436. #if __MonoCS__
  437. pollfds = new Pollfd [2];
  438. pollfds [0] = new Pollfd ();
  439. pollfds [0].fd = XConnectionNumber (DisplayHandle);
  440. pollfds [0].events = PollEvents.POLLIN;
  441. pollfds [1] = new Pollfd ();
  442. pollfds [1].fd = wake_receive.Handle.ToInt32 ();
  443. pollfds [1].events = PollEvents.POLLIN;
  444. #endif
  445. Keyboard = new X11Keyboard(DisplayHandle, FosterParent);
  446. Dnd = new X11Dnd (DisplayHandle, Keyboard);
  447. DoubleClickInterval = 500;
  448. HoverState.Interval = 500;
  449. HoverState.Timer = new Timer();
  450. HoverState.Timer.Enabled = false;
  451. HoverState.Timer.Interval = HoverState.Interval;
  452. HoverState.Timer.Tick += new EventHandler(MouseHover);
  453. HoverState.Size = new Size(4, 4);
  454. HoverState.X = -1;
  455. HoverState.Y = -1;
  456. ActiveWindow = IntPtr.Zero;
  457. FocusWindow = IntPtr.Zero;
  458. ModalWindows = new Stack(3);
  459. MouseState = MouseButtons.None;
  460. mouse_position = new Point(0, 0);
  461. Caret.Timer = new Timer();
  462. Caret.Timer.Interval = 500; // FIXME - where should this number come from?
  463. Caret.Timer.Tick += new EventHandler(CaretCallback);
  464. SetupAtoms();
  465. // Grab atom changes off the root window to catch certain WM events
  466. XSelectInput(DisplayHandle, RootWindow, new IntPtr ((int) (EventMask.PropertyChangeMask | Keyboard.KeyEventMask)));
  467. // Handle any upcoming errors
  468. ErrorHandler = new XErrorHandler(HandleError);
  469. XSetErrorHandler(ErrorHandler);
  470. } else {
  471. throw new ArgumentNullException("Display", "Could not open display (X-Server required. Check you DISPLAY environment variable)");
  472. }
  473. }
  474. #endregion // Internal Methods
  475. #region Methods
  476. [Conditional ("DriverDebug")]
  477. static void DriverDebug (string format, params object [] args)
  478. {
  479. Console.WriteLine (String.Format (format, args));
  480. }
  481. int unixtime() {
  482. TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));
  483. return (int) t.TotalSeconds;
  484. }
  485. static void SetupAtoms() {
  486. // make sure this array stays in sync with the statements below
  487. string [] atom_names = new string[] {
  488. "WM_PROTOCOLS",
  489. "WM_DELETE_WINDOW",
  490. "WM_TAKE_FOCUS",
  491. //"_NET_SUPPORTED",
  492. //"_NET_CLIENT_LIST",
  493. //"_NET_NUMBER_OF_DESKTOPS",
  494. "_NET_DESKTOP_GEOMETRY",
  495. //"_NET_DESKTOP_VIEWPORT",
  496. "_NET_CURRENT_DESKTOP",
  497. //"_NET_DESKTOP_NAMES",
  498. "_NET_ACTIVE_WINDOW",
  499. "_NET_WORKAREA",
  500. //"_NET_SUPPORTING_WM_CHECK",
  501. //"_NET_VIRTUAL_ROOTS",
  502. //"_NET_DESKTOP_LAYOUT",
  503. //"_NET_SHOWING_DESKTOP",
  504. //"_NET_CLOSE_WINDOW",
  505. //"_NET_MOVERESIZE_WINDOW",
  506. "_NET_WM_MOVERESIZE",
  507. //"_NET_RESTACK_WINDOW",
  508. //"_NET_REQUEST_FRAME_EXTENTS",
  509. "_NET_WM_NAME",
  510. //"_NET_WM_VISIBLE_NAME",
  511. //"_NET_WM_ICON_NAME",
  512. //"_NET_WM_VISIBLE_ICON_NAME",
  513. //"_NET_WM_DESKTOP",
  514. "_NET_WM_WINDOW_TYPE",
  515. "_NET_WM_STATE",
  516. //"_NET_WM_ALLOWED_ACTIONS",
  517. //"_NET_WM_STRUT",
  518. //"_NET_WM_STRUT_PARTIAL",
  519. //"_NET_WM_ICON_GEOMETRY",
  520. "_NET_WM_ICON",
  521. //"_NET_WM_PID",
  522. //"_NET_WM_HANDLED_ICONS",
  523. "_NET_WM_USER_TIME",
  524. "_NET_FRAME_EXTENTS",
  525. //"_NET_WM_PING",
  526. //"_NET_WM_SYNC_REQUEST",
  527. "_NET_SYSTEM_TRAY_OPCODE",
  528. //"_NET_SYSTEM_TRAY_ORIENTATION",
  529. "_NET_WM_STATE_MAXIMIZED_HORZ",
  530. "_NET_WM_STATE_MAXIMIZED_VERT",
  531. "_NET_WM_STATE_HIDDEN",
  532. "_XEMBED",
  533. "_XEMBED_INFO",
  534. "_MOTIF_WM_HINTS",
  535. "_NET_WM_STATE_SKIP_TASKBAR",
  536. "_NET_WM_STATE_ABOVE",
  537. "_NET_WM_STATE_MODAL",
  538. "_NET_WM_CONTEXT_HELP",
  539. "_NET_WM_WINDOW_OPACITY",
  540. //"_NET_WM_WINDOW_TYPE_DESKTOP",
  541. //"_NET_WM_WINDOW_TYPE_DOCK",
  542. //"_NET_WM_WINDOW_TYPE_TOOLBAR",
  543. //"_NET_WM_WINDOW_TYPE_MENU",
  544. "_NET_WM_WINDOW_TYPE_UTILITY",
  545. // "_NET_WM_WINDOW_TYPE_DIALOG",
  546. //"_NET_WM_WINDOW_TYPE_SPLASH",
  547. "_NET_WM_WINDOW_TYPE_NORMAL",
  548. "CLIPBOARD",
  549. "PRIMARY",
  550. "COMPOUND_TEXT",
  551. "UTF8_STRING",
  552. "UTF16_STRING",
  553. "RICHTEXTFORMAT",
  554. "TARGETS",
  555. "_SWF_AsyncAtom",
  556. "_SWF_PostMessageAtom",
  557. "_SWF_HoverAtom" };
  558. IntPtr[] atoms = new IntPtr [atom_names.Length];;
  559. XInternAtoms (DisplayHandle, atom_names, atom_names.Length, false, atoms);
  560. int off = 0;
  561. WM_PROTOCOLS = atoms [off++];
  562. WM_DELETE_WINDOW = atoms [off++];
  563. WM_TAKE_FOCUS = atoms [off++];
  564. //_NET_SUPPORTED = atoms [off++];
  565. //_NET_CLIENT_LIST = atoms [off++];
  566. //_NET_NUMBER_OF_DESKTOPS = atoms [off++];
  567. _NET_DESKTOP_GEOMETRY = atoms [off++];
  568. //_NET_DESKTOP_VIEWPORT = atoms [off++];
  569. _NET_CURRENT_DESKTOP = atoms [off++];
  570. //_NET_DESKTOP_NAMES = atoms [off++];
  571. _NET_ACTIVE_WINDOW = atoms [off++];
  572. _NET_WORKAREA = atoms [off++];
  573. //_NET_SUPPORTING_WM_CHECK = atoms [off++];
  574. //_NET_VIRTUAL_ROOTS = atoms [off++];
  575. //_NET_DESKTOP_LAYOUT = atoms [off++];
  576. //_NET_SHOWING_DESKTOP = atoms [off++];
  577. //_NET_CLOSE_WINDOW = atoms [off++];
  578. //_NET_MOVERESIZE_WINDOW = atoms [off++];
  579. _NET_WM_MOVERESIZE = atoms [off++];
  580. //_NET_RESTACK_WINDOW = atoms [off++];
  581. //_NET_REQUEST_FRAME_EXTENTS = atoms [off++];
  582. _NET_WM_NAME = atoms [off++];
  583. //_NET_WM_VISIBLE_NAME = atoms [off++];
  584. //_NET_WM_ICON_NAME = atoms [off++];
  585. //_NET_WM_VISIBLE_ICON_NAME = atoms [off++];
  586. //_NET_WM_DESKTOP = atoms [off++];
  587. _NET_WM_WINDOW_TYPE = atoms [off++];
  588. _NET_WM_STATE = atoms [off++];
  589. //_NET_WM_ALLOWED_ACTIONS = atoms [off++];
  590. //_NET_WM_STRUT = atoms [off++];
  591. //_NET_WM_STRUT_PARTIAL = atoms [off++];
  592. //_NET_WM_ICON_GEOMETRY = atoms [off++];
  593. _NET_WM_ICON = atoms [off++];
  594. //_NET_WM_PID = atoms [off++];
  595. //_NET_WM_HANDLED_ICONS = atoms [off++];
  596. _NET_WM_USER_TIME = atoms [off++];
  597. _NET_FRAME_EXTENTS = atoms [off++];
  598. //_NET_WM_PING = atoms [off++];
  599. //_NET_WM_SYNC_REQUEST = atoms [off++];
  600. _NET_SYSTEM_TRAY_OPCODE = atoms [off++];
  601. //_NET_SYSTEM_TRAY_ORIENTATION = atoms [off++];
  602. _NET_WM_STATE_MAXIMIZED_HORZ = atoms [off++];
  603. _NET_WM_STATE_MAXIMIZED_VERT = atoms [off++];
  604. _NET_WM_STATE_HIDDEN = atoms [off++];
  605. _XEMBED = atoms [off++];
  606. _XEMBED_INFO = atoms [off++];
  607. _MOTIF_WM_HINTS = atoms [off++];
  608. _NET_WM_STATE_SKIP_TASKBAR = atoms [off++];
  609. _NET_WM_STATE_ABOVE = atoms [off++];
  610. _NET_WM_STATE_MODAL = atoms [off++];
  611. _NET_WM_CONTEXT_HELP = atoms [off++];
  612. _NET_WM_WINDOW_OPACITY = atoms [off++];
  613. //_NET_WM_WINDOW_TYPE_DESKTOP = atoms [off++];
  614. //_NET_WM_WINDOW_TYPE_DOCK = atoms [off++];
  615. //_NET_WM_WINDOW_TYPE_TOOLBAR = atoms [off++];
  616. //_NET_WM_WINDOW_TYPE_MENU = atoms [off++];
  617. _NET_WM_WINDOW_TYPE_UTILITY = atoms [off++];
  618. // _NET_WM_WINDOW_TYPE_DIALOG = atoms [off++];
  619. //_NET_WM_WINDOW_TYPE_SPLASH = atoms [off++];
  620. _NET_WM_WINDOW_TYPE_NORMAL = atoms [off++];
  621. CLIPBOARD = atoms [off++];
  622. PRIMARY = atoms [off++];
  623. OEMTEXT = atoms [off++];
  624. UTF8_STRING = atoms [off++];
  625. UTF16_STRING = atoms [off++];
  626. RICHTEXTFORMAT = atoms [off++];
  627. TARGETS = atoms [off++];
  628. AsyncAtom = atoms [off++];
  629. PostAtom = atoms [off++];
  630. HoverState.Atom = atoms [off++];
  631. //DIB = (IntPtr)Atom.XA_PIXMAP;
  632. _NET_SYSTEM_TRAY_S = XInternAtom (DisplayHandle, "_NET_SYSTEM_TRAY_S" + ScreenNo.ToString(), false);
  633. }
  634. void GetSystrayManagerWindow() {
  635. XGrabServer(DisplayHandle);
  636. SystrayMgrWindow = XGetSelectionOwner(DisplayHandle, _NET_SYSTEM_TRAY_S);
  637. XUngrabServer(DisplayHandle);
  638. XFlush(DisplayHandle);
  639. }
  640. void SendNetWMMessage(IntPtr window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2) {
  641. SendNetWMMessage (window, message_type, l0, l1, l2, IntPtr.Zero);
  642. }
  643. void SendNetWMMessage(IntPtr window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2, IntPtr l3) {
  644. XEvent xev;
  645. xev = new XEvent();
  646. xev.ClientMessageEvent.type = XEventName.ClientMessage;
  647. xev.ClientMessageEvent.send_event = true;
  648. xev.ClientMessageEvent.window = window;
  649. xev.ClientMessageEvent.message_type = message_type;
  650. xev.ClientMessageEvent.format = 32;
  651. xev.ClientMessageEvent.ptr1 = l0;
  652. xev.ClientMessageEvent.ptr2 = l1;
  653. xev.ClientMessageEvent.ptr3 = l2;
  654. xev.ClientMessageEvent.ptr4 = l3;
  655. XSendEvent(DisplayHandle, RootWindow, false, new IntPtr ((int) (EventMask.SubstructureRedirectMask | EventMask.SubstructureNotifyMask)), ref xev);
  656. }
  657. void SendNetClientMessage(IntPtr window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2) {
  658. XEvent xev;
  659. xev = new XEvent();
  660. xev.ClientMessageEvent.type = XEventName.ClientMessage;
  661. xev.ClientMessageEvent.send_event = true;
  662. xev.ClientMessageEvent.window = window;
  663. xev.ClientMessageEvent.message_type = message_type;
  664. xev.ClientMessageEvent.format = 32;
  665. xev.ClientMessageEvent.ptr1 = l0;
  666. xev.ClientMessageEvent.ptr2 = l1;
  667. xev.ClientMessageEvent.ptr3 = l2;
  668. XSendEvent(DisplayHandle, window, false, new IntPtr ((int)EventMask.NoEventMask), ref xev);
  669. }
  670. // For WM_LBUTTONDOWN, WM_MBUTTONDOWN, WM_RBUTTONDOWN, WM_XBUTTONDOWN
  671. // WM_CREATE and WM_DESTROY causes
  672. void SendParentNotify(IntPtr child, Msg cause, int x, int y)
  673. {
  674. Hwnd hwnd;
  675. if (child == IntPtr.Zero) {
  676. return;
  677. }
  678. hwnd = Hwnd.GetObjectFromWindow (child);
  679. if (hwnd == null) {
  680. return;
  681. }
  682. if (hwnd.Handle == IntPtr.Zero) {
  683. return;
  684. }
  685. if (ExStyleSet ((int) hwnd.initial_ex_style, WindowExStyles.WS_EX_NOPARENTNOTIFY)) {
  686. return;
  687. }
  688. if (hwnd.Parent == null) {
  689. return;
  690. }
  691. if (hwnd.Parent.Handle == IntPtr.Zero) {
  692. return;
  693. }
  694. if (cause == Msg.WM_CREATE || cause == Msg.WM_DESTROY) {
  695. SendMessage(hwnd.Parent.Handle, Msg.WM_PARENTNOTIFY, Control.MakeParam((int)cause, 0), child);
  696. } else {
  697. SendMessage(hwnd.Parent.Handle, Msg.WM_PARENTNOTIFY, Control.MakeParam((int)cause, 0), Control.MakeParam(x, y));
  698. }
  699. SendParentNotify (hwnd.Parent.Handle, cause, x, y);
  700. }
  701. bool StyleSet (int s, WindowStyles ws)
  702. {
  703. return (s & (int)ws) == (int)ws;
  704. }
  705. bool ExStyleSet (int ex, WindowExStyles exws)
  706. {
  707. return (ex & (int)exws) == (int)exws;
  708. }
  709. internal static Rectangle TranslateClientRectangleToXClientRectangle (Hwnd hwnd)
  710. {
  711. return TranslateClientRectangleToXClientRectangle (hwnd, Control.FromHandle (hwnd.Handle));
  712. }
  713. internal static Rectangle TranslateClientRectangleToXClientRectangle (Hwnd hwnd, Control ctrl)
  714. {
  715. /*
  716. * If this is a form with no window manager, X is handling all the border and caption painting
  717. * so remove that from the area (since the area we set of the window here is the part of the window
  718. * we're painting in only)
  719. */
  720. Rectangle rect = hwnd.ClientRect;
  721. Form form = ctrl as Form;
  722. CreateParams cp = null;
  723. if (form != null)
  724. cp = form.GetCreateParams ();
  725. if (form != null && (form.window_manager == null && !cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW))) {
  726. Hwnd.Borders borders = Hwnd.GetBorders (cp, null);
  727. Rectangle xrect = rect;
  728. xrect.Y -= borders.top;
  729. xrect.X -= borders.left;
  730. xrect.Width += borders.left + borders.right;
  731. xrect.Height += borders.top + borders.bottom;
  732. rect = xrect;
  733. }
  734. if (rect.Width < 1 || rect.Height < 1) {
  735. rect.Width = 1;
  736. rect.Height = 1;
  737. rect.X = -5;
  738. rect.Y = -5;
  739. }
  740. return rect;
  741. }
  742. internal static Size TranslateWindowSizeToXWindowSize (CreateParams cp)
  743. {
  744. return TranslateWindowSizeToXWindowSize (cp, new Size (cp.Width, cp.Height));
  745. }
  746. internal static Size TranslateWindowSizeToXWindowSize (CreateParams cp, Size size)
  747. {
  748. /*
  749. * If this is a form with no window manager, X is handling all the border and caption painting
  750. * so remove that from the area (since the area we set of the window here is the part of the window
  751. * we're painting in only)
  752. */
  753. Form form = cp.control as Form;
  754. if (form != null && (form.window_manager == null && !cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW))) {
  755. Hwnd.Borders borders = Hwnd.GetBorders (cp, null);
  756. Size xrect = size;
  757. xrect.Width -= borders.left + borders.right;
  758. xrect.Height -= borders.top + borders.bottom;
  759. size = xrect;
  760. }
  761. if (size.Height == 0)
  762. size.Height = 1;
  763. if (size.Width == 0)
  764. size.Width = 1;
  765. return size;
  766. }
  767. internal static Size TranslateXWindowSizeToWindowSize (CreateParams cp, int xWidth, int xHeight)
  768. {
  769. /*
  770. * If this is a form with no window manager, X is handling all the border and caption painting
  771. * so remove that from the area (since the area we set of the window here is the part of the window
  772. * we're painting in only)
  773. */
  774. Size rect = new Size (xWidth, xHeight);
  775. Form form = cp.control as Form;
  776. if (form != null && (form.window_manager == null && !cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW))) {
  777. Hwnd.Borders borders = Hwnd.GetBorders (cp, null);
  778. Size xrect = rect;
  779. xrect.Width += borders.left + borders.right;
  780. xrect.Height += borders.top + borders.bottom;
  781. rect = xrect;
  782. }
  783. return rect;
  784. }
  785. internal static Point GetTopLevelWindowLocation (Hwnd hwnd)
  786. {
  787. IntPtr dummy;
  788. int x, y;
  789. Hwnd.Borders frame;
  790. XTranslateCoordinates (DisplayHandle, hwnd.whole_window, RootWindow, 0, 0, out x, out y, out dummy);
  791. frame = FrameExtents (hwnd.whole_window);
  792. x -= frame.left;
  793. y -= frame.top;
  794. return new Point (x, y);
  795. }
  796. void DeriveStyles(int Style, int ExStyle, out FormBorderStyle border_style, out bool border_static, out TitleStyle title_style, out int caption_height, out int tool_caption_height) {
  797. caption_height = 0;
  798. tool_caption_height = 19;
  799. border_static = false;
  800. if (StyleSet (Style, WindowStyles.WS_CHILD)) {
  801. if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_CLIENTEDGE)) {
  802. border_style = FormBorderStyle.Fixed3D;
  803. } else if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_STATICEDGE)) {
  804. border_style = FormBorderStyle.Fixed3D;
  805. border_static = true;
  806. } else if (!StyleSet (Style, WindowStyles.WS_BORDER)) {
  807. border_style = FormBorderStyle.None;
  808. } else {
  809. border_style = FormBorderStyle.FixedSingle;
  810. }
  811. title_style = TitleStyle.None;
  812. if (StyleSet (Style, WindowStyles.WS_CAPTION)) {
  813. caption_height = 19;
  814. if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
  815. title_style = TitleStyle.Tool;
  816. } else {
  817. title_style = TitleStyle.Normal;
  818. }
  819. }
  820. if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_MDICHILD)) {
  821. caption_height = 19;
  822. if (StyleSet (Style, WindowStyles.WS_OVERLAPPEDWINDOW) ||
  823. ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
  824. border_style = (FormBorderStyle) 0xFFFF;
  825. } else {
  826. border_style = FormBorderStyle.None;
  827. }
  828. }
  829. } else {
  830. title_style = TitleStyle.None;
  831. if (StyleSet (Style, WindowStyles.WS_CAPTION)) {
  832. if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
  833. title_style = TitleStyle.Tool;
  834. } else {
  835. title_style = TitleStyle.Normal;
  836. }
  837. }
  838. border_style = FormBorderStyle.None;
  839. if (StyleSet (Style, WindowStyles.WS_THICKFRAME)) {
  840. if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
  841. border_style = FormBorderStyle.SizableToolWindow;
  842. } else {
  843. border_style = FormBorderStyle.Sizable;
  844. }
  845. } else {
  846. if (StyleSet (Style, WindowStyles.WS_CAPTION)) {
  847. if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_CLIENTEDGE)) {
  848. border_style = FormBorderStyle.Fixed3D;
  849. } else if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_STATICEDGE)) {
  850. border_style = FormBorderStyle.Fixed3D;
  851. border_static = true;
  852. } else if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_DLGMODALFRAME)) {
  853. border_style = FormBorderStyle.FixedDialog;
  854. } else if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
  855. border_style = FormBorderStyle.FixedToolWindow;
  856. } else if (StyleSet (Style, WindowStyles.WS_BORDER)) {
  857. border_style = FormBorderStyle.FixedSingle;
  858. }
  859. } else {
  860. if (StyleSet (Style, WindowStyles.WS_BORDER)) {
  861. border_style = FormBorderStyle.FixedSingle;
  862. }
  863. }
  864. }
  865. }
  866. }
  867. void SetHwndStyles(Hwnd hwnd, CreateParams cp) {
  868. DeriveStyles(cp.Style, cp.ExStyle, out hwnd.border_style, out hwnd.border_static, out hwnd.title_style, out hwnd.caption_height, out hwnd.tool_caption_height);
  869. }
  870. void SetWMStyles(Hwnd hwnd, CreateParams cp) {
  871. MotifWmHints mwmHints;
  872. MotifFunctions functions;
  873. MotifDecorations decorations;
  874. int[] atoms;
  875. int atom_count;
  876. Rectangle client_rect;
  877. Form form;
  878. IntPtr window_type;
  879. bool hide_from_taskbar;
  880. IntPtr transient_for_parent;
  881. // Windows we manage ourselves don't need WM window styles.
  882. if (cp.HasWindowManager && !cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW)) {
  883. return;
  884. }
  885. atoms = new int[8];
  886. mwmHints = new MotifWmHints();
  887. functions = 0;
  888. decorations = 0;
  889. window_type = _NET_WM_WINDOW_TYPE_NORMAL;
  890. transient_for_parent = IntPtr.Zero;
  891. mwmHints.flags = (IntPtr)(MotifFlags.Functions | MotifFlags.Decorations);
  892. mwmHints.functions = (IntPtr)0;
  893. mwmHints.decorations = (IntPtr)0;
  894. form = cp.control as Form;
  895. if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
  896. /* tool windows get no window manager
  897. decorations.
  898. */
  899. /* just because the window doesn't get any decorations doesn't
  900. mean we should disable the functions. for instance, without
  901. MotifFunctions.Maximize, changing the windowstate to Maximized
  902. is ignored by metacity. */
  903. functions |= MotifFunctions.Move | MotifFunctions.Resize | MotifFunctions.Minimize | MotifFunctions.Maximize;
  904. } else if (form != null && form.FormBorderStyle == FormBorderStyle.None) {
  905. /* allow borderless window to be maximized */
  906. functions |= MotifFunctions.All | MotifFunctions.Resize;
  907. } else {
  908. if (StyleSet (cp.Style, WindowStyles.WS_CAPTION)) {
  909. functions |= MotifFunctions.Move;
  910. decorations |= MotifDecorations.Title | MotifDecorations.Menu;
  911. }
  912. if (StyleSet (cp.Style, WindowStyles.WS_THICKFRAME)) {
  913. functions |= MotifFunctions.Move | MotifFunctions.Resize;
  914. decorations |= MotifDecorations.Border | MotifDecorations.ResizeH;
  915. }
  916. if (StyleSet (cp.Style, WindowStyles.WS_MINIMIZEBOX)) {
  917. functions |= MotifFunctions.Minimize;
  918. decorations |= MotifDecorations.Minimize;
  919. }
  920. if (StyleSet (cp.Style, WindowStyles.WS_MAXIMIZEBOX)) {
  921. functions |= MotifFunctions.Maximize;
  922. decorations |= MotifDecorations.Maximize;
  923. }
  924. if (StyleSet (cp.Style, WindowStyles.WS_SIZEBOX)) {
  925. functions |= MotifFunctions.Resize;
  926. decorations |= MotifDecorations.ResizeH;
  927. }
  928. if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_DLGMODALFRAME)) {
  929. decorations |= MotifDecorations.Border;
  930. }
  931. if (StyleSet (cp.Style, WindowStyles.WS_BORDER)) {
  932. decorations |= MotifDecorations.Border;
  933. }
  934. if (StyleSet (cp.Style, WindowStyles.WS_DLGFRAME)) {
  935. decorations |= MotifDecorations.Border;
  936. }
  937. if (StyleSet (cp.Style, WindowStyles.WS_SYSMENU)) {
  938. functions |= MotifFunctions.Close;
  939. }
  940. else {
  941. functions &= ~(MotifFunctions.Maximize | MotifFunctions.Minimize | MotifFunctions.Close);
  942. decorations &= ~(MotifDecorations.Menu | MotifDecorations.Maximize | MotifDecorations.Minimize);
  943. if (cp.Caption == "") {
  944. functions &= ~MotifFunctions.Move;
  945. decorations &= ~(MotifDecorations.Title | MotifDecorations.ResizeH);
  946. }
  947. }
  948. }
  949. if ((functions & MotifFunctions.Resize) == 0) {
  950. hwnd.fixed_size = true;
  951. Rectangle fixed_rectangle = new Rectangle (cp.X, cp.Y, cp.Width, cp.Height);
  952. SetWindowMinMax(hwnd.Handle, fixed_rectangle, fixed_rectangle.Size, fixed_rectangle.Size, cp);
  953. } else {
  954. hwnd.fixed_size = false;
  955. }
  956. mwmHints.functions = (IntPtr)functions;
  957. mwmHints.decorations = (IntPtr)decorations;
  958. DriverDebug ("SetWMStyles ({0}, {1}) functions = {2}, decorations = {3}", hwnd, cp, functions, decorations);
  959. if (cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW)) {
  960. // needed! map toolwindows to _NET_WM_WINDOW_TYPE_UTILITY to make newer metacity versions happy
  961. // and get those windows in front of their parents
  962. window_type = _NET_WM_WINDOW_TYPE_UTILITY;
  963. } else {
  964. window_type = _NET_WM_WINDOW_TYPE_NORMAL;
  965. }
  966. if (!cp.IsSet (WindowExStyles.WS_EX_APPWINDOW)) {
  967. hide_from_taskbar = true;
  968. } else if (cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW) && form != null && form.Parent != null && !form.ShowInTaskbar) {
  969. hide_from_taskbar = true;
  970. } else {
  971. hide_from_taskbar = false;
  972. }
  973. if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
  974. if (form != null && !hwnd.reparented) {
  975. if (form.Owner != null && form.Owner.Handle != IntPtr.Zero) {
  976. Hwnd owner_hwnd = Hwnd.ObjectFromHandle (form.Owner.Handle);
  977. if (owner_hwnd != null)
  978. transient_for_parent = owner_hwnd.whole_window;
  979. }
  980. }
  981. }
  982. if (StyleSet (cp.Style, WindowStyles.WS_POPUP) && (hwnd.parent != null) && (hwnd.parent.whole_window != IntPtr.Zero)) {
  983. transient_for_parent = hwnd.parent.whole_window;
  984. }
  985. FormWindowState current_state = GetWindowState (hwnd.Handle);
  986. if (current_state == (FormWindowState)(-1))
  987. current_state = FormWindowState.Normal;
  988. client_rect = TranslateClientRectangleToXClientRectangle (hwnd);
  989. lock (XlibLock) {
  990. atom_count = 0;
  991. atoms [0] = window_type.ToInt32 ();
  992. XChangeProperty (DisplayHandle, hwnd.whole_window, _NET_WM_WINDOW_TYPE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
  993. XChangeProperty(DisplayHandle, hwnd.whole_window, _MOTIF_WM_HINTS, _MOTIF_WM_HINTS, 32, PropertyMode.Replace, ref mwmHints, 5);
  994. if (transient_for_parent != IntPtr.Zero) {
  995. XSetTransientForHint (DisplayHandle, hwnd.whole_window, transient_for_parent);
  996. }
  997. MoveResizeWindow(DisplayHandle, hwnd.client_window, client_rect.X, client_rect.Y, client_rect.Width, client_rect.Height);
  998. if (hide_from_taskbar) {
  999. /* this line keeps the window from showing up in gnome's taskbar */
  1000. atoms[atom_count++] = _NET_WM_STATE_SKIP_TASKBAR.ToInt32();
  1001. }
  1002. /* we need to add these atoms in the
  1003. * event we're maximized, since we're
  1004. * replacing the existing
  1005. * _NET_WM_STATE here. If we don't
  1006. * add them, future calls to
  1007. * GetWindowState will return Normal
  1008. * for a window which is maximized. */
  1009. if (current_state == FormWindowState.Maximized) {
  1010. atoms[atom_count++] = _NET_WM_STATE_MAXIMIZED_HORZ.ToInt32();
  1011. atoms[atom_count++] = _NET_WM_STATE_MAXIMIZED_VERT.ToInt32();
  1012. }
  1013. if (form != null && form.Modal) {
  1014. atoms[atom_count++] = _NET_WM_STATE_MODAL.ToInt32 ();
  1015. }
  1016. XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_STATE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, atom_count);
  1017. atom_count = 0;
  1018. IntPtr[] atom_ptrs = new IntPtr[2];
  1019. atom_ptrs[atom_count++] = WM_DELETE_WINDOW;
  1020. if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_CONTEXTHELP)) {
  1021. atom_ptrs[atom_count++] = _NET_WM_CONTEXT_HELP;
  1022. }
  1023. XSetWMProtocols(DisplayHandle, hwnd.whole_window, atom_ptrs, atom_count);
  1024. }
  1025. }
  1026. void SetIcon(Hwnd hwnd, Icon icon)
  1027. {
  1028. if (icon == null) {
  1029. // XXX
  1030. // This really needs to do whatever it
  1031. // takes to remove the window manager
  1032. // menu, not just delete the ICON
  1033. // property. This will cause metacity
  1034. // to use the "no icon set" icon, and
  1035. // we'll still have an icon.
  1036. XDeleteProperty (DisplayHandle, hwnd.whole_window, _NET_WM_ICON);
  1037. }
  1038. else {
  1039. Bitmap bitmap;
  1040. int size;
  1041. IntPtr[] data;
  1042. int index;
  1043. bitmap = icon.ToBitmap();
  1044. index = 0;
  1045. size = bitmap.Width * bitmap.Height + 2;
  1046. data = new IntPtr[size];
  1047. data[index++] = (IntPtr)bitmap.Width;
  1048. data[index++] = (IntPtr)bitmap.Height;
  1049. for (int y = 0; y < bitmap.Height; y++) {
  1050. for (int x = 0; x < bitmap.Width; x++) {
  1051. data[index++] = (IntPtr)bitmap.GetPixel (x, y).ToArgb ();
  1052. }
  1053. }
  1054. XChangeProperty (DisplayHandle, hwnd.whole_window,
  1055. _NET_WM_ICON, (IntPtr)Atom.XA_CARDINAL, 32,
  1056. PropertyMode.Replace, data, size);
  1057. }
  1058. }
  1059. void WakeupMain () {
  1060. try {
  1061. wake.Send (new byte [] { 0xFF });
  1062. } catch (SocketException ex) {
  1063. if (ex.SocketErrorCode != SocketError.WouldBlock) {
  1064. throw;
  1065. }
  1066. }
  1067. }
  1068. XEventQueue ThreadQueue(Thread thread) {
  1069. XEventQueue queue;
  1070. queue = (XEventQueue)MessageQueues[thread];
  1071. if (queue == null) {
  1072. queue = new XEventQueue(thread);
  1073. MessageQueues[thread] = queue;
  1074. }
  1075. return queue;
  1076. }
  1077. void TranslatePropertyToClipboard(IntPtr property) {
  1078. IntPtr actual_atom;
  1079. int actual_format;
  1080. IntPtr nitems;
  1081. IntPtr bytes_after;
  1082. IntPtr prop = IntPtr.Zero;
  1083. Clipboard.Item = null;
  1084. XGetWindowProperty(DisplayHandle, FosterParent, property, IntPtr.Zero, new IntPtr (0x7fffffff), true, (IntPtr)Atom.AnyPropertyType, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
  1085. if ((long)nitems > 0) {
  1086. if (property == (IntPtr)Atom.XA_STRING) {
  1087. // Xamarin-5116: PtrToStringAnsi expects to get UTF-8, but we might have
  1088. // Latin-1 instead.
  1089. var s = Marshal.PtrToStringAnsi (prop);
  1090. if (string.IsNullOrEmpty (s)) {
  1091. var sb = new StringBuilder ();
  1092. for (int i = 0; i < (int)nitems; i++) {
  1093. var b = Marshal.ReadByte (prop, i);
  1094. sb.Append ((char)b);
  1095. }
  1096. s = sb.ToString ();
  1097. }
  1098. // Some X managers/apps pass unicode chars as escaped strings, so
  1099. // we may need to unescape them.
  1100. Clipboard.Item = UnescapeUnicodeFromAnsi (s);
  1101. } else if (property == (IntPtr)Atom.XA_BITMAP) {
  1102. // FIXME - convert bitmap to image
  1103. } else if (property == (IntPtr)Atom.XA_PIXMAP) {
  1104. // FIXME - convert pixmap to image
  1105. } else if (property == OEMTEXT) {
  1106. Clipboard.Item = UnescapeUnicodeFromAnsi (Marshal.PtrToStringAnsi(prop));
  1107. } else if (property == UTF8_STRING) {
  1108. byte [] buffer = new byte [(int)nitems];
  1109. for (int i = 0; i < (int)nitems; i++)
  1110. buffer [i] = Marshal.ReadByte (prop, i);
  1111. Clipboard.Item = Encoding.UTF8.GetString (buffer);
  1112. } else if (property == UTF16_STRING) {
  1113. Clipboard.Item = Marshal.PtrToStringUni (prop, Encoding.Unicode.GetMaxCharCount ((int)nitems));
  1114. } else if (property == RICHTEXTFORMAT)
  1115. Clipboard.Item = Marshal.PtrToStringAnsi(prop);
  1116. else if (DataFormats.ContainsFormat (property.ToInt32 ())) {
  1117. if (DataFormats.GetFormat (property.ToInt32 ()).is_serializable) {
  1118. MemoryStream memory_stream = new MemoryStream ((int)nitems);
  1119. for (int i = 0; i < (int)nitems; i++)
  1120. memory_stream.WriteByte (Marshal.ReadByte (prop, i));
  1121. memory_stream.Position = 0;
  1122. BinaryFormatter formatter = new BinaryFormatter ();
  1123. Clipboard.Item = formatter.Deserialize (memory_stream);
  1124. memory_stream.Close ();
  1125. }
  1126. }
  1127. XFree(prop);
  1128. }
  1129. }
  1130. string UnescapeUnicodeFromAnsi (string value)
  1131. {
  1132. if (value == null || value.IndexOf ("\\u") == -1)
  1133. return value;
  1134. StringBuilder sb = new StringBuilder (value.Length);
  1135. int start, pos;
  1136. start = pos = 0;
  1137. while (start < value.Length) {
  1138. pos = value.IndexOf ("\\u", start);
  1139. if (pos == -1)
  1140. break;
  1141. sb.Append (value, start, pos - start);
  1142. pos += 2;
  1143. start = pos;
  1144. int length = 0;
  1145. while (pos < value.Length) {
  1146. if (!ValidHexDigit (value [pos]))
  1147. break;
  1148. length++;
  1149. pos++;
  1150. }
  1151. int res;
  1152. if (!Int32.TryParse (value.Substring (start, length), System.Globalization.NumberStyles.HexNumber,
  1153. null, out res))
  1154. return value; // Error, return the unescaped original value.
  1155. sb.Append ((char)res);
  1156. start = pos;
  1157. }
  1158. // Append any remaining data.
  1159. if (start < value.Length)
  1160. sb.Append (value, start, value.Length - start);
  1161. return sb.ToString ();
  1162. }
  1163. private static bool ValidHexDigit (char e)
  1164. {
  1165. return Char.IsDigit (e) || (e >= 'A' && e <= 'F') || (e >= 'a' && e <= 'f');
  1166. }
  1167. void AddExpose (Hwnd hwnd, bool client, int x, int y, int width, int height) {
  1168. // Don't waste time
  1169. if ((hwnd == null) || (x > hwnd.Width) || (y > hwnd.Height) || ((x + width) < 0) || ((y + height) < 0)) {
  1170. return;
  1171. }
  1172. // Keep the invalid area as small as needed
  1173. if ((x + width) > hwnd.width) {
  1174. width = hwnd.width - x;
  1175. }
  1176. if ((y + height) > hwnd.height) {
  1177. height = hwnd.height - y;
  1178. }
  1179. if (client) {
  1180. hwnd.AddInvalidArea(x, y, width, height);
  1181. if (!hwnd.expose_pending) {
  1182. if (!hwnd.nc_expose_pending) {
  1183. hwnd.Queue.Paint.Enqueue(hwnd);
  1184. }
  1185. hwnd.expose_pending = true;
  1186. }
  1187. } else {
  1188. hwnd.AddNcInvalidArea (x, y, width, height);
  1189. if (!hwnd.nc_expose_pending) {
  1190. if (!hwnd.expose_pending) {
  1191. hwnd.Queue.Paint.Enqueue(hwnd);
  1192. }
  1193. hwnd.nc_expose_pending = true;
  1194. }
  1195. }
  1196. }
  1197. static Hwnd.Borders FrameExtents (IntPtr window)
  1198. {
  1199. IntPtr actual_atom;
  1200. int actual_format;
  1201. IntPtr nitems;
  1202. IntPtr bytes_after;
  1203. IntPtr prop = IntPtr.Zero;
  1204. Hwnd.Borders rect = new Hwnd.Borders ();
  1205. XGetWindowProperty (DisplayHandle, window, _NET_FRAME_EXTENTS, IntPtr.Zero, new IntPtr (16), false, (IntPtr)Atom.XA_CARDINAL, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
  1206. if (prop != IntPtr.Zero) {
  1207. if (nitems.ToInt32 () == 4) {
  1208. rect.left = Marshal.ReadInt32 (prop, 0);
  1209. rect.right = Marshal.ReadInt32 (prop, IntPtr.Size);
  1210. rect.top = Marshal.ReadInt32 (prop, 2 * IntPtr.Size);
  1211. rect.bottom = Marshal.ReadInt32 (prop, 3 * IntPtr.Size);
  1212. }
  1213. XFree (prop);
  1214. }
  1215. return rect;
  1216. }
  1217. void AddConfigureNotify (XEvent xevent) {
  1218. Hwnd hwnd;
  1219. hwnd = Hwnd.GetObjectFromWindow(xevent.ConfigureEvent.window);
  1220. // Don't waste time
  1221. if (hwnd == null || hwnd.zombie) {
  1222. return;
  1223. }
  1224. if ((xevent.ConfigureEvent.window == hwnd.whole_window)/* && (xevent.ConfigureEvent.window == xevent.ConfigureEvent.xevent)*/) {
  1225. if (hwnd.parent == null) {
  1226. // The location given by the event is not reliable between different wm's,
  1227. // so use an alternative way of getting it.
  1228. Point location = GetTopLevelWindowLocation (hwnd);
  1229. hwnd.x = location.X;
  1230. hwnd.y = location.Y;
  1231. }
  1232. // XXX this sucks. this isn't thread safe
  1233. Control ctrl = Control.FromHandle (hwnd.Handle);
  1234. Size TranslatedSize;
  1235. if (ctrl != null) {
  1236. TranslatedSize = TranslateXWindowSizeToWindowSize (ctrl.GetCreateParams (), xevent.ConfigureEvent.width, xevent.ConfigureEvent.height);
  1237. } else {
  1238. TranslatedSize = new Size (xevent.ConfigureEvent.width, xevent.ConfigureEvent.height);
  1239. }
  1240. hwnd.width = TranslatedSize.Width;
  1241. hwnd.height = TranslatedSize.Height;
  1242. hwnd.ClientRect = Rectangle.Empty;
  1243. DriverDebug ("AddConfigureNotify (hwnd.Handle = {1}, final hwnd.rect = {0}, reported rect={2})",
  1244. new Rectangle (hwnd.x, hwnd.y, hwnd.width, hwnd.height), hwnd.Handle,
  1245. new Rectangle (xevent.ConfigureEvent.x, xevent.ConfigureEvent.y, xevent.ConfigureEvent.width, xevent.ConfigureEvent.width));
  1246. lock (hwnd.configure_lock) {
  1247. if (!hwnd.configure_pending) {
  1248. hwnd.Queue.EnqueueLocked (xevent);
  1249. hwnd.configure_pending = true;
  1250. }
  1251. }
  1252. }
  1253. // We drop configure events for Client windows
  1254. }
  1255. void ShowCaret() {
  1256. if ((Caret.gc == IntPtr.Zero) || Caret.On) {
  1257. return;
  1258. }
  1259. Caret.On = true;
  1260. lock (XlibLock) {
  1261. XDrawLine(DisplayHandle, Caret.Window, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
  1262. }
  1263. }
  1264. void HideCaret() {
  1265. if ((Caret.gc == IntPtr.Zero) || !Caret.On) {
  1266. return;
  1267. }
  1268. Caret.On = false;
  1269. lock (XlibLock) {
  1270. XDrawLine(DisplayHandle, Caret.Window, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
  1271. }
  1272. }
  1273. int NextTimeout (ArrayList timers, DateTime now) {
  1274. int timeout = 0;
  1275. foreach (Timer timer in timers) {
  1276. int next = (int) (timer.Expires - now).TotalMilliseconds;
  1277. if (next < 0) {
  1278. return 0; // Have a timer that has already expired
  1279. }
  1280. if (next < timeout) {
  1281. timeout = next;
  1282. }
  1283. }
  1284. if (timeout < Timer.Minimum) {
  1285. timeout = Timer.Minimum;
  1286. }
  1287. if (timeout > 1000)
  1288. timeout = 1000;
  1289. return timeout;
  1290. }
  1291. void CheckTimers (ArrayList timers, DateTime now) {
  1292. int count;
  1293. count = timers.Count;
  1294. if (count == 0)
  1295. return;
  1296. for (int i = 0; i < timers.Count; i++) {
  1297. Timer timer;
  1298. timer = (Timer) timers [i];
  1299. if (timer.Enabled && timer.Expires <= now && !timer.Busy) {
  1300. // Timer ticks:
  1301. // - Before MainForm.OnLoad if DoEvents () is called.
  1302. // - After MainForm.OnLoad if not.
  1303. //
  1304. if (in_doevents ||
  1305. (Application.MWFThread.Current.Context != null &&
  1306. (Application.MWFThread.Current.Context.MainForm == null ||
  1307. Application.MWFThread.Current.Context.MainForm.IsLoaded))) {
  1308. timer.Busy = true;
  1309. timer.Update (now);
  1310. timer.FireTick ();
  1311. timer.Busy = false;
  1312. }
  1313. }
  1314. }
  1315. }
  1316. void WaitForHwndMessage (Hwnd hwnd, Msg message) {
  1317. WaitForHwndMessage (hwnd, message, false);
  1318. }
  1319. void WaitForHwndMessage (Hwnd hwnd, Msg message, bool process) {
  1320. MSG msg = new MSG ();
  1321. XEventQueue queue;
  1322. queue = ThreadQueue(Thread.CurrentThread);
  1323. queue.DispatchIdle = false;
  1324. bool done = false;
  1325. string key = hwnd.Handle + ":" + message;
  1326. if (!messageHold.ContainsKey (key))
  1327. messageHold.Add (key, 1);
  1328. else
  1329. messageHold[key] = ((int)messageHold[key]) + 1;
  1330. do {
  1331. DebugHelper.WriteLine ("Waiting for message " + message + " on hwnd " + String.Format("0x{0:x}", hwnd.Handle.ToInt32 ()));
  1332. DebugHelper.Indent ();
  1333. if (PeekMessage(queue, ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)) {
  1334. if ((Msg)msg.message == Msg.WM_QUIT) {
  1335. PostQuitMessage (0);
  1336. done = true;
  1337. }
  1338. else {
  1339. DebugHelper.WriteLine ("PeekMessage got " + msg);
  1340. if (msg.hwnd == hwnd.Handle) {
  1341. if ((Msg)msg.message == message) {
  1342. if (process) {
  1343. TranslateMessage (ref msg);
  1344. DispatchMessage (ref msg);
  1345. }
  1346. break;
  1347. }
  1348. else if ((Msg)msg.message == Msg.WM_DESTROY)
  1349. done = true;
  1350. }
  1351. TranslateMessage (ref msg);
  1352. DispatchMessage (ref msg);
  1353. }
  1354. }
  1355. done = !messageHold.ContainsKey (key) || ((int)messageHold[key] < 1) || done;
  1356. } while (!done);
  1357. messageHold.Remove (key);
  1358. DebugHelper.Unindent ();
  1359. DebugHelper.WriteLine ("Finished waiting for " + key);
  1360. queue.DispatchIdle = true;
  1361. }
  1362. void MapWindow(Hwnd hwnd, WindowType windows) {
  1363. if (!hwnd.mapped) {
  1364. Form f = Control.FromHandle(hwnd.Handle) as Form;
  1365. if (f != null) {
  1366. if (f.WindowState == FormWindowState.Normal) {
  1367. f.waiting_showwindow = true;
  1368. SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, (IntPtr)1, IntPtr.Zero);
  1369. }
  1370. }
  1371. // it's possible that our Hwnd is no
  1372. // longer valid after making that
  1373. // SendMessage call, so check here.
  1374. if (hwnd.zombie)
  1375. return;
  1376. if ((windows & WindowType.Whole) != 0) {
  1377. XMapWindow(DisplayHandle, hwnd.whole_window);
  1378. }
  1379. if ((windows & WindowType.Client) != 0) {
  1380. XMapWindow(DisplayHandle, hwnd.client_window);
  1381. }
  1382. hwnd.mapped = true;
  1383. if (f != null) {
  1384. if (f.waiting_showwindow) {
  1385. WaitForHwndMessage (hwnd, Msg.WM_SHOWWINDOW);
  1386. CreateParams cp = f.GetCreateParams();
  1387. if (!ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_MDICHILD) &&
  1388. !StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
  1389. WaitForHwndMessage (hwnd, Msg.WM_ACTIVATE, true);
  1390. }
  1391. }
  1392. }
  1393. }
  1394. }
  1395. void UnmapWindow(Hwnd hwnd, WindowType windows) {
  1396. if (hwnd.mapped) {
  1397. Form f = null;
  1398. if (Control.FromHandle(hwnd.Handle) is Form) {
  1399. f = Control.FromHandle(hwnd.Handle) as Form;
  1400. if (f.WindowState == FormWindowState.Normal) {
  1401. f.waiting_showwindow = true;
  1402. SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, IntPtr.Zero, IntPtr.Zero);
  1403. }
  1404. }
  1405. // it's possible that our Hwnd is no
  1406. // longer valid after making that
  1407. // SendMessage call, so check here.
  1408. // FIXME: it is likely wrong, as it has already sent WM_SHOWWINDOW
  1409. if (hwnd.zombie)
  1410. return;
  1411. if ((windows & WindowType.Client) != 0) {
  1412. XUnmapWindow(DisplayHandle, hwnd.client_window);
  1413. }
  1414. if ((windows & WindowType.Whole) != 0) {
  1415. XUnmapWindow(DisplayHandle, hwnd.whole_window);
  1416. }
  1417. hwnd.mapped = false;
  1418. if (f != null) {
  1419. if (f.waiting_showwindow) {
  1420. WaitForHwndMessage (hwnd, Msg.WM_SHOWWINDOW);
  1421. CreateParams cp = f.GetCreateParams();
  1422. if (!ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_MDICHILD) &&
  1423. !StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
  1424. WaitForHwndMessage (hwnd, Msg.WM_ACTIVATE, true);
  1425. }
  1426. }
  1427. }
  1428. }
  1429. }
  1430. void UpdateMessageQueue (XEventQueue queue) {
  1431. UpdateMessageQueue(queue, true);
  1432. }
  1433. void UpdateMessageQueue (XEventQueue queue, bool allowIdle) {
  1434. DateTime now;
  1435. int pending;
  1436. Hwnd hwnd;
  1437. now = DateTime.UtcNow;
  1438. lock (XlibLock) {
  1439. pending = XPending (DisplayHandle);
  1440. }
  1441. if (pending == 0 && allowIdle) {
  1442. if ((queue == null || queue.DispatchIdle) && Idle != null) {
  1443. Idle (this, EventArgs.Empty);
  1444. }
  1445. lock (XlibLock) {
  1446. pending = XPending (DisplayHandle);
  1447. }
  1448. }
  1449. if (pending == 0) {
  1450. int timeout = 0;
  1451. if (queue != null) {
  1452. if (queue.Paint.Count > 0)
  1453. return;
  1454. timeout = NextTimeout (queue.timer_list, now);
  1455. }
  1456. if (timeout > 0) {
  1457. #if __MonoCS__
  1458. int length = pollfds.Length - 1;
  1459. lock (wake_waiting_lock) {
  1460. if (wake_waiting == false) {
  1461. length ++;
  1462. wake_waiting = true;
  1463. }
  1464. }
  1465. Syscall.poll (pollfds, (uint)length, timeout);
  1466. // Clean out buffer, so we're not busy-looping on the same data
  1467. if (length == pollfds.Length) {
  1468. if (pollfds[1].revents != 0)
  1469. wake_receive.Receive(network_buffer, 0, 1, SocketFlags.None);
  1470. lock (wake_waiting_lock) {
  1471. wake_waiting = false;
  1472. }
  1473. }
  1474. #endif
  1475. lock (XlibLock) {
  1476. pending = XPending (DisplayHandle);
  1477. }
  1478. }
  1479. }
  1480. if (queue != null)
  1481. CheckTimers (queue.timer_list, now);
  1482. while (true) {
  1483. XEvent xevent = new XEvent ();
  1484. lock (XlibLock) {
  1485. if (XPending (DisplayHandle) == 0)
  1486. break;
  1487. XNextEvent (DisplayHandle, ref xevent);
  1488. if (xevent.AnyEvent.type == XEventName.KeyPress ||
  1489. xevent.AnyEvent.type == XEventName.KeyRelease) {
  1490. // PreFilter() handles "shift key state updates.
  1491. Keyboard.PreFilter (xevent);
  1492. if (XFilterEvent (ref xevent, Keyboard.ClientWindow)) {
  1493. // probably here we could raise WM_IME_KEYDOWN and
  1494. // WM_IME_KEYUP, but I'm not sure it is worthy.
  1495. continue;
  1496. }
  1497. }
  1498. else if (XFilterEvent (ref xevent, IntPtr.Zero))
  1499. continue;
  1500. }
  1501. hwnd = Hwnd.GetObjectFromWindow(xevent.AnyEvent.window);
  1502. if (hwnd == null)
  1503. continue;
  1504. DebugHelper.WriteLine ("UpdateMessageQueue got Event: " + xevent.ToString ());
  1505. switch (xevent.type) {
  1506. case XEventName.Expose:
  1507. AddExpose (hwnd, xevent.ExposeEvent.window == hwnd.ClientWindow, xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
  1508. break;
  1509. case XEventName.SelectionClear: {
  1510. // Should we do something?
  1511. break;
  1512. }
  1513. case XEventName.SelectionRequest: {
  1514. if (Dnd.HandleSelectionRequestEvent (ref xevent))
  1515. break;
  1516. XEvent sel_event;
  1517. sel_event = new XEvent();
  1518. sel_event.SelectionEvent.type = XEventName.SelectionNotify;
  1519. sel_event.SelectionEvent.send_event = true;
  1520. sel_event.SelectionEvent.display = DisplayHandle;
  1521. sel_event.SelectionEvent.selection = xevent.SelectionRequestEvent.selection;
  1522. sel_event.SelectionEvent.target = xevent.SelectionRequestEvent.target;
  1523. sel_event.SelectionEvent.requestor = xevent.SelectionRequestEvent.requestor;
  1524. sel_event.SelectionEvent.time = xevent.SelectionRequestEvent.time;
  1525. sel_event.SelectionEvent.property = IntPtr.Zero;
  1526. IntPtr format_atom = xevent.SelectionRequestEvent.target;
  1527. // Seems that some apps support asking for supported types
  1528. if (format_atom == TARGETS) {
  1529. int[] atoms;
  1530. int atom_count;
  1531. atoms = new int[5];
  1532. atom_count = 0;
  1533. if (Clipboard.IsSourceText) {
  1534. atoms[atom_count++] = (int)Atom.XA_STRING;
  1535. atoms[atom_count++] = (int)OEMTEXT;
  1536. atoms[atom_count++] = (int)UTF8_STRING;
  1537. atoms[atom_count++] = (int)UTF16_STRING;
  1538. atoms[atom_count++] = (int)RICHTEXTFORMAT;
  1539. } else if (Clipboard.IsSourceImage) {
  1540. atoms[atom_count++] = (int)Atom.XA_PIXMAP;
  1541. atoms[atom_count++] = (int)Atom.XA_BITMAP;
  1542. } else {
  1543. // FIXME - handle other types
  1544. }
  1545. XChangeProperty(DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property,
  1546. (IntPtr)xevent.SelectionRequestEvent.target, 32, PropertyMode.Replace, atoms, atom_count);
  1547. sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
  1548. } else if (format_atom == (IntPtr)RICHTEXTFORMAT) {
  1549. string rtf_text = Clipboard.GetRtfText ();
  1550. if (rtf_text != null) {
  1551. // The RTF spec mentions that ascii is enough to contain it
  1552. Byte [] bytes = Encoding.ASCII.GetBytes (rtf_text);
  1553. int buflen = bytes.Length;
  1554. IntPtr buffer = Marshal.AllocHGlobal (buflen);
  1555. for (int i = 0; i < buflen; i++)
  1556. Marshal.WriteByte (buffer, i, bytes[i]);
  1557. XChangeProperty(DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property,
  1558. (IntPtr)xevent.SelectionRequestEvent.target, 8, PropertyMode.Replace, buffer, buflen);
  1559. sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
  1560. Marshal.FreeHGlobal(buffer);
  1561. }
  1562. } else if (Clipboard.IsSourceText &&
  1563. (format_atom == (IntPtr)Atom.XA_STRING
  1564. || format_atom == OEMTEXT
  1565. || format_atom == UTF16_STRING
  1566. || format_atom == UTF8_STRING)) {
  1567. IntPtr buffer = IntPtr.Zero;
  1568. int buflen;
  1569. Encoding encoding = null;
  1570. buflen = 0;
  1571. // Select an encoding depending on the target
  1572. IntPtr target_atom = xevent.SelectionRequestEvent.target;
  1573. if (target_atom == (IntPtr)Atom.XA_STRING || target_atom == OEMTEXT)
  1574. // FIXME - EOMTEXT should encode into ISO2022
  1575. encoding = Encoding.ASCII;
  1576. else if (target_atom == UTF16_STRING)
  1577. encoding = Encoding.Unicode;
  1578. else if (target_atom == UTF8_STRING)
  1579. encoding = Encoding.UTF8;
  1580. Byte [] bytes;
  1581. bytes = encoding.GetBytes (Clipboard.GetPlainText ());
  1582. buffer = Marshal.AllocHGlobal (bytes.Length);
  1583. buflen = bytes.Length;
  1584. for (int i = 0; i < buflen; i++)
  1585. Marshal.WriteByte (buffer, i, bytes [i]);
  1586. if (buffer != IntPtr.Zero) {
  1587. XChangeProperty(DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property, (IntPtr)xevent.SelectionRequestEvent.target, 8, PropertyMode.Replace, buffer, buflen);
  1588. sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
  1589. Marshal.FreeHGlobal(buffer);
  1590. }
  1591. } else if (Clipboard.GetSource (format_atom.ToInt32 ()) != null) { // check if we have an available value of this format
  1592. if (DataFormats.GetFormat (format_atom.ToInt32 ()).is_serializable) {
  1593. object serializable = Clipboard.GetSource (format_atom.ToInt32 ());
  1594. BinaryFormatter formatter = new BinaryFormatter ();
  1595. MemoryStream memory_stream = new MemoryStream ();
  1596. formatter.Serialize (memory_stream, serializable);
  1597. int buflen = (int)memory_stream.Length;
  1598. IntPtr buffer = Marshal.AllocHGlobal (buflen);
  1599. memory_stream.Position = 0;
  1600. for (int i = 0; i < buflen; i++)
  1601. Marshal.WriteByte (buffer, i, (byte)memory_stream.ReadByte ());
  1602. memory_stream.Close ();
  1603. XChangeProperty (DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property, (IntPtr)xevent.SelectionRequestEvent.target,
  1604. 8, PropertyMode.Replace, buffer, buflen);
  1605. sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
  1606. Marshal.FreeHGlobal (buffer);
  1607. }
  1608. } else if (Clipboard.IsSourceImage) {
  1609. if (xevent.SelectionEvent.target == (IntPtr)Atom.XA_PIXMAP) {
  1610. // FIXME - convert image and store as property
  1611. } else if (xevent.SelectionEvent.target == (IntPtr)Atom.XA_PIXMAP) {
  1612. // FIXME - convert image and store as property
  1613. }
  1614. }
  1615. XSendEvent(DisplayHandle, xevent.SelectionRequestEvent.requestor, false, new IntPtr ((int)EventMask.NoEventMask), ref sel_event);
  1616. break;
  1617. }
  1618. case XEventName.SelectionNotify: {
  1619. if (Clipboard.Enumerating) {
  1620. Clipboard.Enumerating = false;
  1621. if (xevent.SelectionEvent.property != IntPtr.Zero) {
  1622. XDeleteProperty(DisplayHandle, FosterParent, (IntPtr)xevent.SelectionEvent.property);
  1623. if (!Clipboard.Formats.Contains(xevent.SelectionEvent.property)) {
  1624. Clipboard.Formats.Add(xevent.SelectionEvent.property);
  1625. DriverDebug("Got supported clipboard atom format: {0}", xevent.SelectionEvent.property);
  1626. }
  1627. }
  1628. } else if (Clipboard.Retrieving) {
  1629. Clipboard.Retrieving = false;
  1630. if (xevent.SelectionEvent.property != IntPtr.Zero) {
  1631. TranslatePropertyToClipboard(xevent.SelectionEvent.property);
  1632. } else {
  1633. Clipboard.ClearSources ();
  1634. Clipboard.Item = null;
  1635. }
  1636. } else {
  1637. Dnd.HandleSelectionNotifyEvent (ref xevent);
  1638. }
  1639. break;
  1640. }
  1641. case XEventName.KeyRelease:
  1642. if (!detectable_key_auto_repeat && XPending (DisplayHandle) != 0) {
  1643. XEvent nextevent = new XEvent ();
  1644. XPeekEvent (DisplayHandle, ref nextevent);
  1645. if (nextevent.type == XEventName.KeyPress &&
  1646. nextevent.KeyEvent.keycode == xevent.KeyEvent.keycode &&
  1647. nextevent.KeyEvent.time == xevent.KeyEvent.time) {
  1648. continue;
  1649. }
  1650. }
  1651. goto case XEventName.KeyPress;
  1652. case XEventName.MotionNotify: {
  1653. XEvent peek;
  1654. /* we can't do motion compression across threads, so just punt if we don't match up */
  1655. if (Thread.CurrentThread == hwnd.Queue.Thread && hwnd.Queue.Count > 0) {
  1656. peek = hwnd.Queue.Peek();
  1657. if (peek.AnyEvent.type == XEventName.MotionNotify) {
  1658. continue;
  1659. }
  1660. }
  1661. goto case XEventName.KeyPress;
  1662. }
  1663. case XEventName.KeyPress:
  1664. hwnd.Queue.EnqueueLocked (xevent);
  1665. /* Process KeyPresses immediately. Otherwise multiple Compose messages as a result of a
  1666. * single physical keypress are not processed correctly */
  1667. return;
  1668. case XEventName.ButtonPress:
  1669. case XEventName.ButtonRelease:
  1670. case XEventName.EnterNotify:
  1671. case XEventName.LeaveNotify:
  1672. case XEventName.CreateNotify:
  1673. case XEventName.DestroyNotify:
  1674. case XEventName.FocusIn:
  1675. case XEventName.FocusOut:
  1676. case XEventName.ClientMessage:
  1677. case XEventName.ReparentNotify:
  1678. case XEventName.MapNotify:
  1679. case XEventName.UnmapNotify:
  1680. hwnd.Queue.EnqueueLocked (xevent);
  1681. break;
  1682. case XEventName.ConfigureNotify:
  1683. AddConfigureNotify(xevent);
  1684. break;
  1685. case XEventName.PropertyNotify:
  1686. DriverDebug ("UpdateMessageQueue (), got Event: {0}", xevent.ToString ());
  1687. if (xevent.PropertyEvent.atom == _NET_ACTIVE_WINDOW) {
  1688. IntPtr actual_atom;
  1689. int actual_format;
  1690. IntPtr nitems;
  1691. IntPtr bytes_after;
  1692. IntPtr prop = IntPtr.Zero;
  1693. IntPtr prev_active;
  1694. prev_active = ActiveWindow;
  1695. XGetWindowProperty(DisplayHandle, RootWindow, _NET_ACTIVE_WINDOW, IntPtr.Zero, new IntPtr (1), false, (IntPtr)Atom.XA_WINDOW, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
  1696. if (((long)nitems > 0) && (prop != IntPtr.Zero)) {
  1697. ActiveWindow = Hwnd.GetHandleFromWindow((IntPtr)Marshal.ReadInt32(prop));
  1698. XFree(prop);
  1699. DebugHelper.WriteLine ("PropertyNotify: _NET_ACTIVE_WINDOW: previous = 0x{0:x}, new = 0x{1:x}", prev_active.ToInt32 (), ActiveWindow.ToInt32 ());
  1700. if (prev_active != ActiveWindow) {
  1701. if (prev_active != IntPtr.Zero) {
  1702. PostMessage(prev_active, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_INACTIVE, IntPtr.Zero);
  1703. }
  1704. if (ActiveWindow != IntPtr.Zero) {
  1705. PostMessage(ActiveWindow, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_ACTIVE, IntPtr.Zero);
  1706. }
  1707. }
  1708. if (ModalWindows.Count == 0) {
  1709. break;
  1710. } else {
  1711. // Modality Handling
  1712. //
  1713. // If there is a modal window on the stack and the new active
  1714. // window is MWF window, but not the modal one and not a non-modal
  1715. // child of the modal one, switch back to the modal window.
  1716. //
  1717. // To identify if a non-modal form is child of a modal form
  1718. // we match their ApplicationContexts, which will be the same.
  1719. // This is because each modal form runs the loop with a
  1720. // new ApplicationContext, which is inherited by the non-modal
  1721. // forms.
  1722. Form activeForm = Control.FromHandle (ActiveWindow) as Form;
  1723. if (activeForm != null) {
  1724. Form modalForm = Control.FromHandle ((IntPtr)ModalWindows.Peek()) as Form;
  1725. if (ActiveWindow != (IntPtr)ModalWindows.Peek() &&
  1726. (modalForm == null || activeForm.context == modalForm.context)) {
  1727. Activate((IntPtr)ModalWindows.Peek());
  1728. }
  1729. }
  1730. break;
  1731. }
  1732. }
  1733. }
  1734. else if (xevent.PropertyEvent.atom == _NET_WM_STATE) {
  1735. // invalidate our cache - we'll query again the next time someone does GetWindowState.
  1736. hwnd.cached_window_state = (FormWindowState)(-1);
  1737. PostMessage (hwnd.Handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
  1738. }
  1739. break;
  1740. }
  1741. }
  1742. }
  1743. IntPtr GetMousewParam(int Delta) {
  1744. int result = 0;
  1745. if ((MouseState & MouseButtons.Left) != 0) {
  1746. result |= (int)MsgButtons.MK_LBUTTON;
  1747. }
  1748. if ((MouseState & MouseButtons.Middle) != 0) {
  1749. result |= (int)MsgButtons.MK_MBUTTON;
  1750. }
  1751. if ((MouseState & MouseButtons.Right) != 0) {
  1752. result |= (int)MsgButtons.MK_RBUTTON;
  1753. }
  1754. Keys mods = ModifierKeys;
  1755. if ((mods & Keys.Control) != 0) {
  1756. result |= (int)MsgButtons.MK_CONTROL;
  1757. }
  1758. if ((mods & Keys.Shift) != 0) {
  1759. result |= (int)MsgButtons.MK_SHIFT;
  1760. }
  1761. result |= Delta << 16;
  1762. return (IntPtr)result;
  1763. }
  1764. IntPtr XGetParent(IntPtr handle) {
  1765. IntPtr Root;
  1766. IntPtr Parent;
  1767. IntPtr Children;
  1768. int ChildCount;
  1769. lock (XlibLock) {
  1770. XQueryTree(DisplayHandle, handle, out Root, out Parent, out Children, out ChildCount);
  1771. }
  1772. if (Children!=IntPtr.Zero) {
  1773. lock (XlibLock) {
  1774. XFree(Children);
  1775. }
  1776. }
  1777. return Parent;
  1778. }
  1779. int HandleError (IntPtr display, ref XErrorEvent error_event)
  1780. {
  1781. // we need to workaround a problem with the
  1782. // ordering of destruction of Drawables and
  1783. // Pictures that exists between cairo and
  1784. // RENDER on the server.
  1785. if (error_event.request_code == (XRequest)render_major_opcode
  1786. && error_event.minor_code == 7 /* X_RenderFreePicture from render.h */
  1787. && error_event.error_code == render_first_error + 1 /* BadPicture from render.h */) {
  1788. return 0;
  1789. }
  1790. if (ErrorExceptions) {
  1791. XUngrabPointer (display, IntPtr.Zero);
  1792. throw new XException (error_event.display, error_event.resourceid,
  1793. error_event.serial, error_event.error_code,
  1794. error_event.request_code, error_event.minor_code);
  1795. } else {
  1796. Console.WriteLine("X11 Error encountered: {0}{1}\n",
  1797. XException.GetMessage (error_event.display, error_event.resourceid,
  1798. error_event.serial, error_event.error_code,
  1799. error_event.request_code, error_event.minor_code),
  1800. Environment.StackTrace);
  1801. }
  1802. return 0;
  1803. }
  1804. void AccumulateDestroyedHandles (Control c, ArrayList list)
  1805. {
  1806. DebugHelper.Enter ();
  1807. if (c != null) {
  1808. Control[] controls = c.Controls.GetAllControls ();
  1809. DebugHelper.WriteLine ("Checking control:0x{0:x}", c.IsHandleCreated ? c.Handle.ToInt32() : 0);
  1810. if (c.IsHandleCreated && !c.IsDisposed) {
  1811. Hwnd hwnd = Hwnd.ObjectFromHandle(c.Handle);
  1812. DriverDebug (" + adding {0} to the list of zombie windows", XplatUI.Window (hwnd.Handle));
  1813. DriverDebug (" + parent X window is {0:X}", XGetParent (hwnd.whole_window).ToInt32());
  1814. list.Add (hwnd);
  1815. CleanupCachedWindows (hwnd);
  1816. }
  1817. for (int i = 0; i < controls.Length; i ++) {
  1818. AccumulateDestroyedHandles (controls[i], list);
  1819. }
  1820. }
  1821. DebugHelper.Leave ();
  1822. }
  1823. void CleanupCachedWindows (Hwnd hwnd)
  1824. {
  1825. if (ActiveWindow == hwnd.Handle) {
  1826. SendMessage(hwnd.client_window, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_INACTIVE, IntPtr.Zero);
  1827. ActiveWindow = IntPtr.Zero;
  1828. }
  1829. if (FocusWindow == hwnd.Handle) {
  1830. SendMessage(hwnd.client_window, Msg.WM_KILLFOCUS, IntPtr.Zero, IntPtr.Zero);
  1831. FocusWindow = IntPtr.Zero;
  1832. }
  1833. if (Grab.Hwnd == hwnd.Handle) {
  1834. Grab.Hwnd = IntPtr.Zero;
  1835. Grab.Confined = false;
  1836. }
  1837. DestroyCaret (hwnd.Handle);
  1838. }
  1839. void PerformNCCalc(Hwnd hwnd) {
  1840. XplatUIWin32.NCCALCSIZE_PARAMS ncp;
  1841. IntPtr ptr;
  1842. Rectangle rect;
  1843. rect = new Rectangle (0, 0, hwnd.Width, hwnd.Height);
  1844. ncp = new XplatUIWin32.NCCALCSIZE_PARAMS();
  1845. ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ncp));
  1846. ncp.rgrc1.left = rect.Left;
  1847. ncp.rgrc1.top = rect.Top;
  1848. ncp.rgrc1.right = rect.Right;
  1849. ncp.rgrc1.bottom = rect.Bottom;
  1850. Marshal.StructureToPtr(ncp, ptr, true);
  1851. NativeWindow.WndProc(hwnd.client_window, Msg.WM_NCCALCSIZE, (IntPtr)1, ptr);
  1852. ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(ptr, typeof(XplatUIWin32.NCCALCSIZE_PARAMS));
  1853. Marshal.FreeHGlobal(ptr);
  1854. rect = new Rectangle(ncp.rgrc1.left, ncp.rgrc1.top, ncp.rgrc1.right - ncp.rgrc1.left, ncp.rgrc1.bottom - ncp.rgrc1.top);
  1855. hwnd.ClientRect = rect;
  1856. rect = TranslateClientRectangleToXClientRectangle (hwnd);
  1857. if (hwnd.visible) {
  1858. MoveResizeWindow (DisplayHandle, hwnd.client_window, rect.X, rect.Y, rect.Width, rect.Height);
  1859. }
  1860. AddExpose (hwnd, hwnd.WholeWindow == hwnd.ClientWindow, 0, 0, hwnd.Width, hwnd.Height);
  1861. }
  1862. #endregion // Methods
  1863. #region Callbacks
  1864. void MouseHover(object sender, EventArgs e) {
  1865. XEvent xevent;
  1866. Hwnd hwnd;
  1867. HoverState.Timer.Enabled = false;
  1868. if (HoverState.Window != IntPtr.Zero) {
  1869. hwnd = Hwnd.GetObjectFromWindow(HoverState.Window);
  1870. if (hwnd != null) {
  1871. xevent = new XEvent ();
  1872. xevent.type = XEventName.ClientMessage;
  1873. xevent.ClientMessageEvent.display = DisplayHandle;
  1874. xevent.ClientMessageEvent.window = HoverState.Window;
  1875. xevent.ClientMessageEvent.message_type = HoverState.Atom;
  1876. xevent.ClientMessageEvent.format = 32;
  1877. xevent.ClientMessageEvent.ptr1 = (IntPtr) (HoverState.Y << 16 | HoverState.X);
  1878. hwnd.Queue.EnqueueLocked (xevent);
  1879. WakeupMain ();
  1880. }
  1881. }
  1882. }
  1883. void CaretCallback(object sender, EventArgs e) {
  1884. if (Caret.Paused) {
  1885. return;
  1886. }
  1887. Caret.On = !Caret.On;
  1888. XDrawLine(DisplayHandle, Caret.Hwnd, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
  1889. }
  1890. #endregion // Callbacks
  1891. #region Public Properties
  1892. internal override int CaptionHeight {
  1893. get {
  1894. return 19;
  1895. }
  1896. }
  1897. internal override Size CursorSize {
  1898. get {
  1899. int x;
  1900. int y;
  1901. if (XQueryBestCursor(DisplayHandle, RootWindow, 32, 32, out x, out y) != 0) {
  1902. return new Size(x, y);
  1903. } else {
  1904. return new Size(16, 16);
  1905. }
  1906. }
  1907. }
  1908. internal override bool DragFullWindows {
  1909. get {
  1910. return true;
  1911. }
  1912. }
  1913. internal override Size DragSize {
  1914. get {
  1915. return new Size(4, 4);
  1916. }
  1917. }
  1918. internal override Size FrameBorderSize {
  1919. get {
  1920. return new Size (4, 4);
  1921. }
  1922. }
  1923. internal override Size IconSize {
  1924. get {
  1925. IntPtr list;
  1926. XIconSize size;
  1927. int count;
  1928. if (XGetIconSizes(DisplayHandle, RootWindow, out list, out count) != 0) {
  1929. long current;
  1930. int largest;
  1931. current = (long)list;
  1932. largest = 0;
  1933. size = new XIconSize();
  1934. for (int i = 0; i < count; i++) {
  1935. size = (XIconSize)Marshal.PtrToStructure((IntPtr)current, size.GetType());
  1936. current += Marshal.SizeOf(size);
  1937. // Look for our preferred size
  1938. if (size.min_width == 32) {
  1939. XFree(list);
  1940. return new Size(32, 32);
  1941. }
  1942. if (size.max_width == 32) {
  1943. XFree(list);
  1944. return new Size(32, 32);
  1945. }
  1946. if (size.min_width < 32 && size.max_width > 32) {
  1947. int x;
  1948. // check if we can fit one
  1949. x = size.min_width;
  1950. while (x < size.max_width) {
  1951. x += size.width_inc;
  1952. if (x == 32) {
  1953. XFree(list);
  1954. return new Size(32, 32);
  1955. }
  1956. }
  1957. }
  1958. if (largest < size.max_width) {
  1959. largest = size.max_width;
  1960. }
  1961. }
  1962. // We didn't find a match or we wouldn't be here
  1963. return new Size(largest, largest);
  1964. } else {
  1965. return new Size(32, 32);
  1966. }
  1967. }
  1968. }
  1969. internal override int KeyboardSpeed {
  1970. get{
  1971. //
  1972. // A lot harder: need to do:
  1973. // XkbQueryExtension(0x08051008, 0xbfffdf4c, 0xbfffdf50, 0xbfffdf54, 0xbfffdf58) = 1
  1974. // XkbAllocKeyboard(0x08051008, 0xbfffdf4c, 0xbfffdf50, 0xbfffdf54, 0xbfffdf58) = 0x080517a8
  1975. // XkbGetControls(0x08051008, 1, 0x080517a8, 0xbfffdf54, 0xbfffdf58) = 0
  1976. //
  1977. // And from that we can tell the repetition rate
  1978. //
  1979. // Notice, the values must map to:
  1980. // [0, 31] which maps to 2.5 to 30 repetitions per second.
  1981. //
  1982. return 0;
  1983. }
  1984. }
  1985. internal override int KeyboardDelay {
  1986. get {
  1987. //
  1988. // Return values must range from 0 to 4, 0 meaning 250ms,
  1989. // and 4 meaning 1000 ms.
  1990. //
  1991. return 1; // ie, 500 ms
  1992. }
  1993. }
  1994. internal override Size MaxWindowTrackSize {
  1995. get {
  1996. return new Size (WorkingArea.Width, WorkingArea.Height);
  1997. }
  1998. }
  1999. internal override bool MenuAccessKeysUnderlined {
  2000. get {
  2001. return false;
  2002. }
  2003. }
  2004. internal override Size MinimizedWindowSpacingSize {
  2005. get {
  2006. return new Size(1, 1);
  2007. }
  2008. }
  2009. internal override Size MinimumWindowSize {
  2010. get {
  2011. return new Size(110, 22);
  2012. }
  2013. }
  2014. internal override Size MinimumFixedToolWindowSize {
  2015. get { return new Size (27, 22); }
  2016. }
  2017. internal override Size MinimumSizeableToolWindowSize {
  2018. get { return new Size (37, 22); }
  2019. }
  2020. internal override Size MinimumNoBorderWindowSize {
  2021. get { return new Size (2, 2); }
  2022. }
  2023. internal override Keys ModifierKeys {
  2024. get {
  2025. return Keyboard.ModifierKeys;
  2026. }
  2027. }
  2028. internal override Size SmallIconSize {
  2029. get {
  2030. IntPtr list;
  2031. XIconSize size;
  2032. int count;
  2033. if (XGetIconSizes(DisplayHandle, RootWindow, out list, out count) != 0) {
  2034. long current;
  2035. int smallest;
  2036. current = (long)list;
  2037. smallest = 0;
  2038. size = new XIconSize();
  2039. for (int i = 0; i < count; i++) {
  2040. size = (XIconSize)Marshal.PtrToStructure((IntPtr)current, size.GetType());
  2041. current += Marshal.SizeOf(size);
  2042. // Look for our preferred size
  2043. if (size.min_width == 16) {
  2044. XFree(list);
  2045. return new Size(16, 16);
  2046. }
  2047. if (size.max_width == 16) {
  2048. XFree(list);
  2049. return new Size(16, 16);
  2050. }
  2051. if (size.min_width < 16 && size.max_width > 16) {
  2052. int x;
  2053. // check if we can fit one
  2054. x = size.min_width;
  2055. while (x < size.max_width) {
  2056. x += size.width_inc;
  2057. if (x == 16) {
  2058. XFree(list);
  2059. return new Size(16, 16);
  2060. }
  2061. }
  2062. }
  2063. if (smallest == 0 || smallest > size.min_width) {
  2064. smallest = size.min_width;
  2065. }
  2066. }
  2067. // We didn't find a match or we wouldn't be here
  2068. return new Size(smallest, smallest);
  2069. } else {
  2070. return new Size(16, 16);
  2071. }
  2072. }
  2073. }
  2074. internal override int MouseButtonCount {
  2075. get {
  2076. return 3;
  2077. }
  2078. }
  2079. internal override bool MouseButtonsSwapped {
  2080. get {
  2081. return false; // FIXME - how to detect?
  2082. }
  2083. }
  2084. internal override Point MousePosition {
  2085. get {
  2086. return mouse_position;
  2087. }
  2088. }
  2089. internal override Size MouseHoverSize {
  2090. get {
  2091. return new Size (1, 1);
  2092. }
  2093. }
  2094. internal override int MouseHoverTime {
  2095. get {
  2096. return HoverState.Interval;
  2097. }
  2098. }
  2099. internal override bool MouseWheelPresent {
  2100. get {
  2101. return true; // FIXME - how to detect?
  2102. }
  2103. }
  2104. internal override MouseButtons MouseButtons {
  2105. get {
  2106. return MouseState;
  2107. }
  2108. }
  2109. internal override Rectangle VirtualScreen {
  2110. get {
  2111. IntPtr actual_atom;
  2112. int actual_format;
  2113. IntPtr nitems;
  2114. IntPtr bytes_after;
  2115. IntPtr prop = IntPtr.Zero;
  2116. int width;
  2117. int height;
  2118. XGetWindowProperty(DisplayHandle, RootWindow, _NET_DESKTOP_GEOMETRY, IntPtr.Zero, new IntPtr (256), false, (IntPtr)Atom.XA_CARDINAL, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
  2119. if ((long)nitems < 2)
  2120. goto failsafe;
  2121. width = Marshal.ReadIntPtr(prop, 0).ToInt32();
  2122. height = Marshal.ReadIntPtr(prop, IntPtr.Size).ToInt32();
  2123. XFree(prop);
  2124. return new Rectangle(0, 0, width, height);
  2125. failsafe:
  2126. XWindowAttributes attributes=new XWindowAttributes();
  2127. lock (XlibLock) {
  2128. XGetWindowAttributes(DisplayHandle, XRootWindow(DisplayHandle, 0), ref attributes);
  2129. }
  2130. return new Rectangle(0, 0, attributes.width, attributes.height);
  2131. }
  2132. }
  2133. internal override Rectangle WorkingArea {
  2134. get {
  2135. IntPtr actual_atom;
  2136. int actual_format;
  2137. IntPtr nitems;
  2138. IntPtr bytes_after;
  2139. IntPtr prop = IntPtr.Zero;
  2140. int width;
  2141. int height;
  2142. int current_desktop;
  2143. int x;
  2144. int y;
  2145. XGetWindowProperty(DisplayHandle, RootWindow, _NET_CURRENT_DESKTOP, IntPtr.Zero, new IntPtr(1), false, (IntPtr)Atom.XA_CARDINAL, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
  2146. if ((long)nitems < 1) {
  2147. goto failsafe;
  2148. }
  2149. current_desktop = Marshal.ReadIntPtr(prop, 0).ToInt32();
  2150. XFree(prop);
  2151. XGetWindowProperty(DisplayHandle, RootWindow, _NET_WORKAREA, IntPtr.Zero, new IntPtr (256), false, (IntPtr)Atom.XA_CARDINAL, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
  2152. if ((long)nitems < 4 * (current_desktop + 1)) {
  2153. goto failsafe;
  2154. }
  2155. x = Marshal.ReadIntPtr(prop, IntPtr.Size * 4 * current_desktop).ToInt32();
  2156. y = Marshal.ReadIntPtr(prop, IntPtr.Size * 4 * current_desktop + IntPtr.Size).ToInt32();
  2157. width = Marshal.ReadIntPtr(prop, IntPtr.Size * 4 * current_desktop + IntPtr.Size * 2).ToInt32();
  2158. height = Marshal.ReadIntPtr(prop, IntPtr.Size * 4 * current_desktop + IntPtr.Size * 3).ToInt32();
  2159. XFree(prop);
  2160. return new Rectangle(x, y, width, height);
  2161. failsafe:
  2162. XWindowAttributes attributes=new XWindowAttributes();
  2163. lock (XlibLock) {
  2164. XGetWindowAttributes(DisplayHandle, XRootWindow(DisplayHandle, 0), ref attributes);
  2165. }
  2166. return new Rectangle(0, 0, attributes.width, attributes.height);
  2167. }
  2168. }
  2169. internal override bool ThemesEnabled {
  2170. get {
  2171. return XplatUIX11.themes_enabled;
  2172. }
  2173. }
  2174. #endregion // Public properties
  2175. #region Public Static Methods
  2176. internal override void RaiseIdle (EventArgs e)
  2177. {
  2178. if (Idle != null)
  2179. Idle (this, e);
  2180. }
  2181. internal override IntPtr InitializeDriver()
  2182. {
  2183. lock (this) {
  2184. if (DisplayHandle==IntPtr.Zero) {
  2185. SetDisplay(XOpenDisplay(IntPtr.Zero));
  2186. }
  2187. }
  2188. return IntPtr.Zero;
  2189. }
  2190. internal override void ShutdownDriver(IntPtr token)
  2191. {
  2192. lock (this) {
  2193. if (DisplayHandle!=IntPtr.Zero) {
  2194. XCloseDisplay(DisplayHandle);
  2195. DisplayHandle=IntPtr.Zero;
  2196. }
  2197. }
  2198. }
  2199. internal override void EnableThemes()
  2200. {
  2201. themes_enabled = true;
  2202. }
  2203. internal override void Activate(IntPtr handle)
  2204. {
  2205. Hwnd hwnd;
  2206. hwnd = Hwnd.ObjectFromHandle(handle);
  2207. if (hwnd != null) {
  2208. lock (XlibLock) {
  2209. if (true /* the window manager supports NET_ACTIVE_WINDOW */) {
  2210. SendNetWMMessage(hwnd.whole_window, _NET_ACTIVE_WINDOW, (IntPtr)1, IntPtr.Zero, IntPtr.Zero);
  2211. XEventQueue q = null;
  2212. lock (unattached_timer_list) {
  2213. foreach (Timer t in unattached_timer_list) {
  2214. if (q == null)
  2215. q= (XEventQueue) MessageQueues [Thread.CurrentThread];
  2216. t.thread = q.Thread;
  2217. q.timer_list.Add (t);
  2218. }
  2219. unattached_timer_list.Clear ();
  2220. }
  2221. }
  2222. // else {
  2223. // XRaiseWindow(DisplayHandle, handle);
  2224. // }
  2225. }
  2226. }
  2227. }
  2228. internal override void AudibleAlert(AlertType alert)
  2229. {
  2230. XBell(DisplayHandle, 0);
  2231. return;
  2232. }
  2233. internal override void CaretVisible(IntPtr handle, bool visible)
  2234. {
  2235. if (Caret.Hwnd == handle) {
  2236. if (visible) {
  2237. if (!Caret.Visible) {
  2238. Caret.Visible = true;
  2239. ShowCaret();
  2240. Caret.Timer.Start();
  2241. }
  2242. } else {
  2243. Caret.Visible = false;
  2244. Caret.Timer.Stop();
  2245. HideCaret();
  2246. }
  2247. }
  2248. }
  2249. internal override bool CalculateWindowRect(ref Rectangle ClientRect, CreateParams cp, Menu menu, out Rectangle WindowRect)
  2250. {
  2251. WindowRect = Hwnd.GetWindowRectangle (cp, menu, ClientRect);
  2252. return true;
  2253. }
  2254. internal override void ClientToScreen(IntPtr handle, ref int x, ref int y)
  2255. {
  2256. int dest_x_return;
  2257. int dest_y_return;
  2258. IntPtr child;
  2259. Hwnd hwnd;
  2260. hwnd = Hwnd.ObjectFromHandle(handle);
  2261. lock (XlibLock) {
  2262. XTranslateCoordinates(DisplayHandle, hwnd.client_window, RootWindow, x, y, out dest_x_return, out dest_y_return, out child);
  2263. }
  2264. x = dest_x_return;
  2265. y = dest_y_return;
  2266. }
  2267. internal override int[] ClipboardAvailableFormats(IntPtr handle)
  2268. {
  2269. DataFormats.Format f;
  2270. int[] result;
  2271. f = DataFormats.Format.List;
  2272. if (XGetSelectionOwner(DisplayHandle, CLIPBOARD) == IntPtr.Zero) {
  2273. return null;
  2274. }
  2275. Clipboard.Formats = new ArrayList();
  2276. while (f != null) {
  2277. XConvertSelection(DisplayHandle, CLIPBOARD, (IntPtr)f.Id, (IntPtr)f.Id, FosterParent, IntPtr.Zero);
  2278. Clipboard.Enumerating = true;
  2279. while (Clipboard.Enumerating) {
  2280. UpdateMessageQueue(null, false);
  2281. }
  2282. f = f.Next;
  2283. }
  2284. result = new int[Clipboard.Formats.Count];
  2285. for (int i = 0; i < Clipboard.Formats.Count; i++) {
  2286. result[i] = ((IntPtr)Clipboard.Formats[i]).ToInt32 ();
  2287. }
  2288. Clipboard.Formats = null;
  2289. return result;
  2290. }
  2291. internal override void ClipboardClose(IntPtr handle)
  2292. {
  2293. if (handle != ClipMagic) {
  2294. throw new ArgumentException("handle is not a valid clipboard handle");
  2295. }
  2296. return;
  2297. }
  2298. internal override int ClipboardGetID(IntPtr handle, string format)
  2299. {
  2300. if (handle != ClipMagic) {
  2301. throw new ArgumentException("handle is not a valid clipboard handle");
  2302. }
  2303. if (format == "Text" ) return (int)Atom.XA_STRING;
  2304. else if (format == "Bitmap" ) return (int)Atom.XA_BITMAP;
  2305. //else if (format == "MetaFilePict" ) return 3;
  2306. //else if (format == "SymbolicLink" ) return 4;
  2307. //else if (format == "DataInterchangeFormat" ) return 5;
  2308. //else if (format == "Tiff" ) return 6;
  2309. else if (format == "OEMText" ) return OEMTEXT.ToInt32();
  2310. else if (format == "DeviceIndependentBitmap" ) return (int)Atom.XA_PIXMAP;
  2311. else if (format == "Palette" ) return (int)Atom.XA_COLORMAP; // Useless
  2312. //else if (format == "PenData" ) return 10;
  2313. //else if (format == "RiffAudio" ) return 11;
  2314. //else if (format == "WaveAudio" ) return 12;
  2315. else if (format == "UnicodeText" ) return UTF16_STRING.ToInt32();
  2316. //else if (format == "EnhancedMetafile" ) return 14;
  2317. //else if (format == "FileDrop" ) return 15;
  2318. //else if (format == "Locale" ) return 16;
  2319. else if (format == "Rich Text Format") return RICHTEXTFORMAT.ToInt32 ();
  2320. return XInternAtom(DisplayHandle, format, false).ToInt32();
  2321. }
  2322. internal override IntPtr ClipboardOpen(bool primary_selection)
  2323. {
  2324. if (!primary_selection)
  2325. ClipMagic = CLIPBOARD;
  2326. else
  2327. ClipMagic = PRIMARY;
  2328. return ClipMagic;
  2329. }
  2330. internal override object ClipboardRetrieve(IntPtr handle, int type, XplatUI.ClipboardToObject converter)
  2331. {
  2332. XConvertSelection(DisplayHandle, handle, (IntPtr)type, (IntPtr)type, FosterParent, IntPtr.Zero);
  2333. Clipboard.Retrieving = true;
  2334. while (Clipboard.Retrieving) {
  2335. UpdateMessageQueue(null, false);
  2336. }
  2337. return Clipboard.Item;
  2338. }
  2339. internal override void ClipboardStore (IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter, bool copy)
  2340. {
  2341. Clipboard.Converter = converter;
  2342. if (obj != null) {
  2343. Clipboard.AddSource (type, obj);
  2344. XSetSelectionOwner (DisplayHandle, CLIPBOARD, FosterParent, IntPtr.Zero);
  2345. if (copy) {
  2346. try {
  2347. var clipboardAtom = gdk_atom_intern ("CLIPBOARD", true);
  2348. var clipboard = gtk_clipboard_get (clipboardAtom);
  2349. if (clipboard != null) {
  2350. // for now we only store text
  2351. var text = Clipboard.GetRtfText ();
  2352. if (string.IsNullOrEmpty (text))
  2353. text = Clipboard.GetPlainText ();
  2354. if (!string.IsNullOrEmpty (text)) {
  2355. gtk_clipboard_set_text (clipboard, text, text.Length);
  2356. gtk_clipboard_store (clipboard);
  2357. }
  2358. }
  2359. } catch {
  2360. // ignore any errors - most likely because gtk isn't installed?
  2361. }
  2362. }
  2363. } else {
  2364. // Clearing the selection
  2365. Clipboard.ClearSources ();
  2366. XSetSelectionOwner (DisplayHandle, CLIPBOARD, IntPtr.Zero, IntPtr.Zero);
  2367. }
  2368. }
  2369. internal override void CreateCaret (IntPtr handle, int width, int height)
  2370. {
  2371. XGCValues gc_values;
  2372. Hwnd hwnd;
  2373. hwnd = Hwnd.ObjectFromHandle(handle);
  2374. if (Caret.Hwnd != IntPtr.Zero) {
  2375. DestroyCaret(Caret.Hwnd);
  2376. }
  2377. Caret.Hwnd = handle;
  2378. Caret.Window = hwnd.client_window;
  2379. Caret.Width = width;
  2380. Caret.Height = height;
  2381. Caret.Visible = false;
  2382. Caret.On = false;
  2383. gc_values = new XGCValues();
  2384. gc_values.line_width = width;
  2385. Caret.gc = XCreateGC(DisplayHandle, Caret.Window, new IntPtr ((int)GCFunction.GCLineWidth), ref gc_values);
  2386. if (Caret.gc == IntPtr.Zero) {
  2387. Caret.Hwnd = IntPtr.Zero;
  2388. return;
  2389. }
  2390. XSetFunction(DisplayHandle, Caret.gc, GXFunction.GXinvert);
  2391. }
  2392. internal override IntPtr CreateWindow (CreateParams cp)
  2393. {
  2394. XSetWindowAttributes Attributes;
  2395. Hwnd hwnd;
  2396. Hwnd parent_hwnd = null;
  2397. int X;
  2398. int Y;
  2399. int Width;
  2400. int Height;
  2401. IntPtr ParentHandle;
  2402. IntPtr WholeWindow;
  2403. IntPtr ClientWindow;
  2404. SetWindowValuemask ValueMask;
  2405. int[] atoms;
  2406. hwnd = new Hwnd();
  2407. Attributes = new XSetWindowAttributes();
  2408. X = cp.X;
  2409. Y = cp.Y;
  2410. Width = cp.Width;
  2411. Height = cp.Height;
  2412. if (Width<1) Width=1;
  2413. if (Height<1) Height=1;
  2414. if (cp.Parent != IntPtr.Zero) {
  2415. parent_hwnd = Hwnd.ObjectFromHandle(cp.Parent);
  2416. ParentHandle = parent_hwnd.client_window;
  2417. } else {
  2418. if (StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
  2419. // We need to use our foster parent window until this poor child gets it's parent assigned
  2420. ParentHandle=FosterParent;
  2421. } else {
  2422. ParentHandle=RootWindow;
  2423. }
  2424. }
  2425. // Set the default location location for forms.
  2426. Point next;
  2427. if (cp.control is Form) {
  2428. next = Hwnd.GetNextStackedFormLocation (cp, parent_hwnd);
  2429. X = next.X;
  2430. Y = next.Y;
  2431. }
  2432. ValueMask = SetWindowValuemask.BitGravity | SetWindowValuemask.WinGravity;
  2433. Attributes.bit_gravity = Gravity.NorthWestGravity;
  2434. Attributes.win_gravity = Gravity.NorthWestGravity;
  2435. // Save what's under the toolwindow
  2436. if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
  2437. Attributes.save_under = true;
  2438. ValueMask |= SetWindowValuemask.SaveUnder;
  2439. }
  2440. // If we're a popup without caption we override the WM
  2441. if (StyleSet (cp.Style, WindowStyles.WS_POPUP) && !StyleSet (cp.Style, WindowStyles.WS_CAPTION)) {
  2442. Attributes.override_redirect = true;
  2443. ValueMask |= SetWindowValuemask.OverrideRedirect;
  2444. }
  2445. hwnd.x = X;
  2446. hwnd.y = Y;
  2447. hwnd.width = Width;
  2448. hwnd.height = Height;
  2449. hwnd.parent = Hwnd.ObjectFromHandle(cp.Parent);
  2450. hwnd.initial_style = cp.WindowStyle;
  2451. hwnd.initial_ex_style = cp.WindowExStyle;
  2452. if (StyleSet (cp.Style, WindowStyles.WS_DISABLED)) {
  2453. hwnd.enabled = false;
  2454. }
  2455. ClientWindow = IntPtr.Zero;
  2456. Size XWindowSize = TranslateWindowSizeToXWindowSize (cp);
  2457. Rectangle XClientRect = TranslateClientRectangleToXClientRectangle (hwnd, cp.control);
  2458. lock (XlibLock) {
  2459. WholeWindow = XCreateWindow(DisplayHandle, ParentHandle, X, Y, XWindowSize.Width, XWindowSize.Height, 0, (int)CreateWindowArgs.CopyFromParent, (int)CreateWindowArgs.InputOutput, IntPtr.Zero, new UIntPtr ((uint)ValueMask), ref Attributes);
  2460. if (WholeWindow != IntPtr.Zero) {
  2461. ValueMask &= ~(SetWindowValuemask.OverrideRedirect | SetWindowValuemask.SaveUnder);
  2462. if (CustomVisual != IntPtr.Zero && CustomColormap != IntPtr.Zero) {
  2463. ValueMask = SetWindowValuemask.ColorMap;
  2464. Attributes.colormap = CustomColormap;
  2465. }
  2466. ClientWindow = XCreateWindow(DisplayHandle, WholeWindow, XClientRect.X, XClientRect.Y, XClientRect.Width, XClientRect.Height, 0, (int)CreateWindowArgs.CopyFromParent, (int)CreateWindowArgs.InputOutput, CustomVisual, new UIntPtr ((uint)ValueMask), ref Attributes);
  2467. }
  2468. }
  2469. if ((WholeWindow == IntPtr.Zero) || (ClientWindow == IntPtr.Zero)) {
  2470. throw new Exception("Could not create X11 windows");
  2471. }
  2472. hwnd.Queue = ThreadQueue(Thread.CurrentThread);
  2473. hwnd.WholeWindow = WholeWindow;
  2474. hwnd.ClientWindow = ClientWindow;
  2475. DriverDebug("Created window {0:X} / {1:X} parent {2:X}, Style {3}, ExStyle {4}", ClientWindow.ToInt32(), WholeWindow.ToInt32(), hwnd.parent != null ? hwnd.parent.Handle.ToInt32() : 0, (WindowStyles)cp.Style, (WindowExStyles)cp.ExStyle);
  2476. if (!StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
  2477. if ((X != unchecked((int)0x80000000)) && (Y != unchecked((int)0x80000000))) {
  2478. XSizeHints hints;
  2479. hints = new XSizeHints();
  2480. hints.x = X;
  2481. hints.y = Y;
  2482. hints.flags = (IntPtr)(XSizeHintsFlags.USPosition | XSizeHintsFlags.PPosition);
  2483. XSetWMNormalHints(DisplayHandle, WholeWindow, ref hints);
  2484. }
  2485. }
  2486. lock (XlibLock) {
  2487. XSelectInput(DisplayHandle, hwnd.whole_window, new IntPtr ((int)(SelectInputMask | EventMask.StructureNotifyMask | EventMask.PropertyChangeMask | Keyboard.KeyEventMask)));
  2488. if (hwnd.whole_window != hwnd.client_window)
  2489. XSelectInput(DisplayHandle, hwnd.client_window, new IntPtr ((int)(SelectInputMask | EventMask.StructureNotifyMask | Keyboard.KeyEventMask)));
  2490. }
  2491. if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOPMOST)) {
  2492. atoms = new int[2];
  2493. atoms[0] = _NET_WM_WINDOW_TYPE_NORMAL.ToInt32();
  2494. XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_WINDOW_TYPE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
  2495. XSetTransientForHint (DisplayHandle, hwnd.whole_window, RootWindow);
  2496. }
  2497. SetWMStyles(hwnd, cp);
  2498. // set the group leader
  2499. XWMHints wm_hints = new XWMHints ();
  2500. wm_hints.flags = (IntPtr)(XWMHintsFlags.InputHint | XWMHintsFlags.StateHint | XWMHintsFlags.WindowGroupHint);
  2501. wm_hints.input = !StyleSet (cp.Style, WindowStyles.WS_DISABLED);
  2502. wm_hints.initial_state = StyleSet (cp.Style, WindowStyles.WS_MINIMIZE) ? XInitialState.IconicState : XInitialState.NormalState;
  2503. if (ParentHandle != RootWindow) {
  2504. wm_hints.window_group = hwnd.whole_window;
  2505. } else {
  2506. wm_hints.window_group = ParentHandle;
  2507. }
  2508. lock (XlibLock) {
  2509. XSetWMHints(DisplayHandle, hwnd.whole_window, ref wm_hints );
  2510. }
  2511. if (StyleSet (cp.Style, WindowStyles.WS_MINIMIZE)) {
  2512. SetWindowState(hwnd.Handle, FormWindowState.Minimized);
  2513. } else if (StyleSet (cp.Style, WindowStyles.WS_MAXIMIZE)) {
  2514. SetWindowState(hwnd.Handle, FormWindowState.Maximized);
  2515. }
  2516. // for now make all windows dnd enabled
  2517. Dnd.SetAllowDrop (hwnd, true);
  2518. // Set caption/window title
  2519. Text(hwnd.Handle, cp.Caption);
  2520. SendMessage (hwnd.Handle, Msg.WM_CREATE, (IntPtr)1, IntPtr.Zero /* XXX unused */);
  2521. SendParentNotify (hwnd.Handle, Msg.WM_CREATE, int.MaxValue, int.MaxValue);
  2522. if (StyleSet (cp.Style, WindowStyles.WS_VISIBLE)) {
  2523. hwnd.visible = true;
  2524. MapWindow(hwnd, WindowType.Both);
  2525. if (!(Control.FromHandle(hwnd.Handle) is Form))
  2526. SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, (IntPtr)1, IntPtr.Zero);
  2527. }
  2528. return hwnd.Handle;
  2529. }
  2530. internal override IntPtr CreateWindow(IntPtr Parent, int X, int Y, int Width, int Height)
  2531. {
  2532. CreateParams create_params = new CreateParams();
  2533. create_params.Caption = "";
  2534. create_params.X = X;
  2535. create_params.Y = Y;
  2536. create_params.Width = Width;
  2537. create_params.Height = Height;
  2538. create_params.ClassName=XplatUI.GetDefaultClassName (GetType ());
  2539. create_params.ClassStyle = 0;
  2540. create_params.ExStyle=0;
  2541. create_params.Parent=IntPtr.Zero;
  2542. create_params.Param=0;
  2543. return CreateWindow(create_params);
  2544. }
  2545. internal override IntPtr DefineCursor(Bitmap bitmap, Bitmap mask, Color cursor_pixel, Color mask_pixel, int xHotSpot, int yHotSpot)
  2546. {
  2547. IntPtr cursor;
  2548. Bitmap cursor_bitmap;
  2549. Bitmap cursor_mask;
  2550. Byte[] cursor_bits;
  2551. Byte[] mask_bits;
  2552. Color c_pixel;
  2553. Color m_pixel;
  2554. int width;
  2555. int height;
  2556. IntPtr cursor_pixmap;
  2557. IntPtr mask_pixmap;
  2558. XColor fg;
  2559. XColor bg;
  2560. bool and;
  2561. bool xor;
  2562. if (XQueryBestCursor(DisplayHandle, RootWindow, bitmap.Width, bitmap.Height, out width, out height) == 0) {
  2563. return IntPtr.Zero;
  2564. }
  2565. // Win32 only allows creation cursors of a certain size
  2566. if ((bitmap.Width != width) || (bitmap.Width != height)) {
  2567. cursor_bitmap = new Bitmap(bitmap, new Size(width, height));
  2568. cursor_mask = new Bitmap(mask, new Size(width, height));
  2569. } else {
  2570. cursor_bitmap = bitmap;
  2571. cursor_mask = mask;
  2572. }
  2573. width = cursor_bitmap.Width;
  2574. height = cursor_bitmap.Height;
  2575. cursor_bits = new Byte[(width / 8) * height];
  2576. mask_bits = new Byte[(width / 8) * height];
  2577. for (int y = 0; y < height; y++) {
  2578. for (int x = 0; x < width; x++) {
  2579. c_pixel = cursor_bitmap.GetPixel(x, y);
  2580. m_pixel = cursor_mask.GetPixel(x, y);
  2581. and = c_pixel == cursor_pixel;
  2582. xor = m_pixel == mask_pixel;
  2583. if (!and && !xor) {
  2584. // Black
  2585. // cursor_bits[y * width / 8 + x / 8] &= (byte)~((1 << (x % 8))); // The bit already is 0
  2586. mask_bits[y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
  2587. } else if (and && !xor) {
  2588. // White
  2589. cursor_bits[y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
  2590. mask_bits[y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
  2591. #if notneeded
  2592. } else if (and && !xor) {
  2593. // Screen
  2594. } else if (and && xor) {
  2595. // Inverse Screen
  2596. // X11 doesn't know the 'reverse screen' concept, so we'll treat them the same
  2597. // we want both to be 0 so nothing to be done
  2598. //cursor_bits[y * width / 8 + x / 8] &= (byte)~((1 << (x % 8)));
  2599. //mask_bits[y * width / 8 + x / 8] |= (byte)(01 << (x % 8));
  2600. #endif
  2601. }
  2602. }
  2603. }
  2604. cursor_pixmap = XCreatePixmapFromBitmapData(DisplayHandle, RootWindow, cursor_bits, width, height, (IntPtr)1, (IntPtr)0, 1);
  2605. mask_pixmap = XCreatePixmapFromBitmapData(DisplayHandle, RootWindow, mask_bits, width, height, (IntPtr)1, (IntPtr)0, 1);
  2606. fg = new XColor();
  2607. bg = new XColor();
  2608. fg.pixel = XWhitePixel(DisplayHandle, ScreenNo);
  2609. fg.red = (ushort)65535;
  2610. fg.green = (ushort)65535;
  2611. fg.blue = (ushort)65535;
  2612. bg.pixel = XBlackPixel(DisplayHandle, ScreenNo);
  2613. cursor = XCreatePixmapCursor(DisplayHandle, cursor_pixmap, mask_pixmap, ref fg, ref bg, xHotSpot, yHotSpot);
  2614. XFreePixmap(DisplayHandle, cursor_pixmap);
  2615. XFreePixmap(DisplayHandle, mask_pixmap);
  2616. return cursor;
  2617. }
  2618. internal override Bitmap DefineStdCursorBitmap (StdCursor id)
  2619. {
  2620. CursorFontShape shape;
  2621. string name;
  2622. IntPtr theme;
  2623. int size;
  2624. Bitmap bmp = null;
  2625. try {
  2626. shape = StdCursorToFontShape (id);
  2627. name = shape.ToString ().Replace ("XC_", string.Empty);
  2628. size = XcursorGetDefaultSize (DisplayHandle);
  2629. theme = XcursorGetTheme (DisplayHandle);
  2630. IntPtr images_ptr = XcursorLibraryLoadImages (name, theme, size);
  2631. DriverDebug ("DefineStdCursorBitmap, id={0}, #id={1}, name{2}, size={3}, theme: {4}, images_ptr={5}", id, (int) id, name, size, Marshal.PtrToStringAnsi (theme), images_ptr);
  2632. if (images_ptr == IntPtr.Zero) {
  2633. return null;
  2634. }
  2635. XcursorImages images = (XcursorImages) Marshal.PtrToStructure (images_ptr, typeof (XcursorImages));
  2636. DriverDebug ("DefineStdCursorBitmap, cursor has {0} images", images.nimage);
  2637. if (images.nimage > 0) {
  2638. // We only care about the first image.
  2639. XcursorImage image = (XcursorImage)Marshal.PtrToStructure (Marshal.ReadIntPtr (images.images), typeof (XcursorImage));
  2640. DriverDebug ("DefineStdCursorBitmap, loaded image <size={0}, height={1}, width={2}, xhot={3}, yhot={4}, pixels={5}", image.size, image.height, image.width, image.xhot, image.yhot, image.pixels);
  2641. // A sanity check
  2642. if (image.width <= short.MaxValue && image.height <= short.MaxValue) {
  2643. int [] pixels = new int [image.width * image.height];
  2644. Marshal.Copy (image.pixels, pixels, 0, pixels.Length);
  2645. bmp = new Bitmap (image.width, image.height);
  2646. for (int w = 0; w < image.width; w++) {
  2647. for (int h = 0; h < image.height; h++) {
  2648. bmp.SetPixel (w, h, Color.FromArgb (pixels [h * image.width + w]));
  2649. }
  2650. }
  2651. }
  2652. }
  2653. XcursorImagesDestroy (images_ptr);
  2654. } catch (DllNotFoundException ex) {
  2655. Console.WriteLine ("Could not load libXcursor: " + ex.Message + " (" + ex.GetType ().Name + ")");
  2656. return null;
  2657. }
  2658. return bmp;
  2659. }
  2660. internal override IntPtr DefineStdCursor(StdCursor id)
  2661. {
  2662. CursorFontShape shape;
  2663. IntPtr cursor;
  2664. shape = StdCursorToFontShape (id);
  2665. lock (XlibLock) {
  2666. cursor = XCreateFontCursor(DisplayHandle, shape);
  2667. }
  2668. return cursor;
  2669. }
  2670. internal static CursorFontShape StdCursorToFontShape (StdCursor id)
  2671. {
  2672. CursorFontShape shape;
  2673. // FIXME - define missing shapes
  2674. switch (id) {
  2675. case StdCursor.AppStarting: {
  2676. shape = CursorFontShape.XC_watch;
  2677. break;
  2678. }
  2679. case StdCursor.Arrow: {
  2680. shape = CursorFontShape.XC_top_left_arrow;
  2681. break;
  2682. }
  2683. case StdCursor.Cross: {
  2684. shape = CursorFontShape.XC_crosshair;
  2685. break;
  2686. }
  2687. case StdCursor.Default: {
  2688. shape = CursorFontShape.XC_top_left_arrow;
  2689. break;
  2690. }
  2691. case StdCursor.Hand: {
  2692. shape = CursorFontShape.XC_hand1;
  2693. break;
  2694. }
  2695. case StdCursor.Help: {
  2696. shape = CursorFontShape.XC_question_arrow;
  2697. break;
  2698. }
  2699. case StdCursor.HSplit: {
  2700. shape = CursorFontShape.XC_sb_v_double_arrow;
  2701. break;
  2702. }
  2703. case StdCursor.IBeam: {
  2704. shape = CursorFontShape.XC_xterm;
  2705. break;
  2706. }
  2707. case StdCursor.No: {
  2708. shape = CursorFontShape.XC_circle;
  2709. break;
  2710. }
  2711. case StdCursor.NoMove2D: {
  2712. shape = CursorFontShape.XC_fleur;
  2713. break;
  2714. }
  2715. case StdCursor.NoMoveHoriz: {
  2716. shape = CursorFontShape.XC_fleur;
  2717. break;
  2718. }
  2719. case StdCursor.NoMoveVert: {
  2720. shape = CursorFontShape.XC_fleur;
  2721. break;
  2722. }
  2723. case StdCursor.PanEast: {
  2724. shape = CursorFontShape.XC_fleur;
  2725. break;
  2726. }
  2727. case StdCursor.PanNE: {
  2728. shape = CursorFontShape.XC_fleur;
  2729. break;
  2730. }
  2731. case StdCursor.PanNorth: {
  2732. shape = CursorFontShape.XC_fleur;
  2733. break;
  2734. }
  2735. case StdCursor.PanNW: {
  2736. shape = CursorFontShape.XC_fleur;
  2737. break;
  2738. }
  2739. case StdCursor.PanSE: {
  2740. shape = CursorFontShape.XC_fleur;
  2741. break;
  2742. }
  2743. case StdCursor.PanSouth: {
  2744. shape = CursorFontShape.XC_fleur;
  2745. break;
  2746. }
  2747. case StdCursor.PanSW: {
  2748. shape = CursorFontShape.XC_fleur;
  2749. break;
  2750. }
  2751. case StdCursor.PanWest: {
  2752. shape = CursorFontShape.XC_sizing;
  2753. break;
  2754. }
  2755. case StdCursor.SizeAll: {
  2756. shape = CursorFontShape.XC_fleur;
  2757. break;
  2758. }
  2759. case StdCursor.SizeNESW: {
  2760. shape = CursorFontShape.XC_top_right_corner;
  2761. break;
  2762. }
  2763. case StdCursor.SizeNS: {
  2764. shape = CursorFontShape.XC_sb_v_double_arrow;
  2765. break;
  2766. }
  2767. case StdCursor.SizeNWSE: {
  2768. shape = CursorFontShape.XC_top_left_corner;
  2769. break;
  2770. }
  2771. case StdCursor.SizeWE: {
  2772. shape = CursorFontShape.XC_sb_h_double_arrow;
  2773. break;
  2774. }
  2775. case StdCursor.UpArrow: {
  2776. shape = CursorFontShape.XC_center_ptr;
  2777. break;
  2778. }
  2779. case StdCursor.VSplit: {
  2780. shape = CursorFontShape.XC_sb_h_double_arrow;
  2781. break;
  2782. }
  2783. case StdCursor.WaitCursor: {
  2784. shape = CursorFontShape.XC_watch;
  2785. break;
  2786. }
  2787. default: {
  2788. shape = (CursorFontShape) 0;
  2789. break;
  2790. }
  2791. }
  2792. return shape;
  2793. }
  2794. internal override IntPtr DefWndProc(ref Message msg)
  2795. {
  2796. switch ((Msg)msg.Msg) {
  2797. case Msg.WM_IME_COMPOSITION:
  2798. string s = Keyboard.GetCompositionString ();
  2799. foreach (char c in s)
  2800. SendMessage (msg.HWnd, Msg.WM_IME_CHAR, (IntPtr) c, msg.LParam);
  2801. return IntPtr.Zero;
  2802. case Msg.WM_IME_CHAR:
  2803. // On Windows API it sends two WM_CHAR messages for each byte, but
  2804. // I wonder if it is worthy to emulate it (also no idea how to
  2805. // reconstruct those bytes into chars).
  2806. SendMessage (msg.HWnd, Msg.WM_CHAR, msg.WParam, msg.LParam);
  2807. return IntPtr.Zero;
  2808. case Msg.WM_PAINT: {
  2809. Hwnd hwnd;
  2810. hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
  2811. if (hwnd != null) {
  2812. hwnd.expose_pending = false;
  2813. }
  2814. return IntPtr.Zero;
  2815. }
  2816. case Msg.WM_NCPAINT: {
  2817. Hwnd hwnd;
  2818. hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
  2819. if (hwnd != null) {
  2820. hwnd.nc_expose_pending = false;
  2821. }
  2822. return IntPtr.Zero;
  2823. }
  2824. case Msg.WM_NCCALCSIZE: {
  2825. Hwnd hwnd;
  2826. if (msg.WParam == (IntPtr)1) {
  2827. hwnd = Hwnd.GetObjectFromWindow (msg.HWnd);
  2828. XplatUIWin32.NCCALCSIZE_PARAMS ncp;
  2829. ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure (msg.LParam, typeof (XplatUIWin32.NCCALCSIZE_PARAMS));
  2830. // Add all the stuff X is supposed to draw.
  2831. Control ctrl = Control.FromHandle (hwnd.Handle);
  2832. if (ctrl != null) {
  2833. Hwnd.Borders rect = Hwnd.GetBorders (ctrl.GetCreateParams (), null);
  2834. ncp.rgrc1.top += rect.top;
  2835. ncp.rgrc1.bottom -= rect.bottom;
  2836. ncp.rgrc1.left += rect.left;
  2837. ncp.rgrc1.right -= rect.right;
  2838. Marshal.StructureToPtr (ncp, msg.LParam, true);
  2839. }
  2840. }
  2841. return IntPtr.Zero;
  2842. }
  2843. case Msg.WM_CONTEXTMENU: {
  2844. Hwnd hwnd;
  2845. hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
  2846. if ((hwnd != null) && (hwnd.parent != null)) {
  2847. SendMessage(hwnd.parent.client_window, Msg.WM_CONTEXTMENU, msg.WParam, msg.LParam);
  2848. }
  2849. return IntPtr.Zero;
  2850. }
  2851. case Msg.WM_MOUSEWHEEL: {
  2852. Hwnd hwnd;
  2853. hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
  2854. if ((hwnd != null) && (hwnd.parent != null)) {
  2855. SendMessage(hwnd.parent.client_window, Msg.WM_MOUSEWHEEL, msg.WParam, msg.LParam);
  2856. if (msg.Result == IntPtr.Zero) {
  2857. return IntPtr.Zero;
  2858. }
  2859. }
  2860. return IntPtr.Zero;
  2861. }
  2862. case Msg.WM_SETCURSOR: {
  2863. Hwnd hwnd;
  2864. hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
  2865. if (hwnd == null)
  2866. break; // not sure how this happens, but it does
  2867. // Pass to parent window first
  2868. while ((hwnd.parent != null) && (msg.Result == IntPtr.Zero)) {
  2869. hwnd = hwnd.parent;
  2870. msg.Result = NativeWindow.WndProc(hwnd.Handle, Msg.WM_SETCURSOR, msg.HWnd, msg.LParam);
  2871. }
  2872. if (msg.Result == IntPtr.Zero) {
  2873. IntPtr handle;
  2874. switch((HitTest)(msg.LParam.ToInt32() & 0xffff)) {
  2875. case HitTest.HTBOTTOM: handle = Cursors.SizeNS.handle; break;
  2876. case HitTest.HTBORDER: handle = Cursors.SizeNS.handle; break;
  2877. case HitTest.HTBOTTOMLEFT: handle = Cursors.SizeNESW.handle; break;
  2878. case HitTest.HTBOTTOMRIGHT: handle = Cursors.SizeNWSE.handle; break;
  2879. case HitTest.HTERROR: if ((msg.LParam.ToInt32() >> 16) == (int)Msg.WM_LBUTTONDOWN) {
  2880. AudibleAlert(AlertType.Default);
  2881. }
  2882. handle = Cursors.Default.handle;
  2883. break;
  2884. case HitTest.HTHELP: handle = Cursors.Help.handle; break;
  2885. case HitTest.HTLEFT: handle = Cursors.SizeWE.handle; break;
  2886. case HitTest.HTRIGHT: handle = Cursors.SizeWE.handle; break;
  2887. case HitTest.HTTOP: handle = Cursors.SizeNS.handle; break;
  2888. case HitTest.HTTOPLEFT: handle = Cursors.SizeNWSE.handle; break;
  2889. case HitTest.HTTOPRIGHT: handle = Cursors.SizeNESW.handle; break;
  2890. #if SameAsDefault
  2891. case HitTest.HTGROWBOX:
  2892. case HitTest.HTSIZE:
  2893. case HitTest.HTZOOM:
  2894. case HitTest.HTVSCROLL:
  2895. case HitTest.HTSYSMENU:
  2896. case HitTest.HTREDUCE:
  2897. case HitTest.HTNOWHERE:
  2898. case HitTest.HTMAXBUTTON:
  2899. case HitTest.HTMINBUTTON:
  2900. case HitTest.HTMENU:
  2901. case HitTest.HSCROLL:
  2902. case HitTest.HTBOTTOM:
  2903. case HitTest.HTCAPTION:
  2904. case HitTest.HTCLIENT:
  2905. case HitTest.HTCLOSE:
  2906. #endif
  2907. default: handle = Cursors.Default.handle; break;
  2908. }
  2909. SetCursor(msg.HWnd, handle);
  2910. }
  2911. return (IntPtr)1;
  2912. }
  2913. }
  2914. return IntPtr.Zero;
  2915. }
  2916. internal override void DestroyCaret(IntPtr handle)
  2917. {
  2918. if (Caret.Hwnd == handle) {
  2919. if (Caret.Visible) {
  2920. HideCaret ();
  2921. Caret.Timer.Stop();
  2922. }
  2923. if (Caret.gc != IntPtr.Zero) {
  2924. XFreeGC(DisplayHandle, Caret.gc);
  2925. Caret.gc = IntPtr.Zero;
  2926. }
  2927. Caret.Hwnd = IntPtr.Zero;
  2928. Caret.Visible = false;
  2929. Caret.On = false;
  2930. }
  2931. }
  2932. internal override void DestroyCursor(IntPtr cursor)
  2933. {
  2934. lock (XlibLock) {
  2935. XFreeCursor(DisplayHandle, cursor);
  2936. }
  2937. }
  2938. internal override void DestroyWindow(IntPtr handle)
  2939. {
  2940. Hwnd hwnd;
  2941. hwnd = Hwnd.ObjectFromHandle(handle);
  2942. // The window should never ever be a zombie here, since we should
  2943. // wait until it's completely dead before returning from
  2944. // "destroying" calls, but just in case....
  2945. if (hwnd == null || hwnd.zombie) {
  2946. DriverDebug ("window {0:X} already destroyed", handle.ToInt32());
  2947. return;
  2948. }
  2949. DriverDebug ("Destroying window {0}", XplatUI.Window(hwnd.client_window));
  2950. SendParentNotify (hwnd.Handle, Msg.WM_DESTROY, int.MaxValue, int.MaxValue);
  2951. CleanupCachedWindows (hwnd);
  2952. ArrayList windows = new ArrayList ();
  2953. AccumulateDestroyedHandles (Control.ControlNativeWindow.ControlFromHandle(hwnd.Handle), windows);
  2954. foreach (Hwnd h in windows) {
  2955. SendMessage (h.Handle, Msg.WM_DESTROY, IntPtr.Zero, IntPtr.Zero);
  2956. h.zombie = true;
  2957. }
  2958. lock (XlibLock) {
  2959. if (hwnd.whole_window != IntPtr.Zero) {
  2960. DriverDebug ("XDestroyWindow (whole_window = {0:X})", hwnd.whole_window.ToInt32());
  2961. Keyboard.DestroyICForWindow (hwnd.whole_window);
  2962. XDestroyWindow(DisplayHandle, hwnd.whole_window);
  2963. }
  2964. else if (hwnd.client_window != IntPtr.Zero) {
  2965. DriverDebug ("XDestroyWindow (client_window = {0:X})", hwnd.client_window.ToInt32());
  2966. Keyboard.DestroyICForWindow (hwnd.client_window);
  2967. XDestroyWindow(DisplayHandle, hwnd.client_window);
  2968. }
  2969. }
  2970. }
  2971. internal override IntPtr DispatchMessage(ref MSG msg)
  2972. {
  2973. return NativeWindow.WndProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
  2974. }
  2975. IntPtr GetReversibleScreenGC (Color backColor)
  2976. {
  2977. XGCValues gc_values;
  2978. IntPtr gc;
  2979. uint pixel;
  2980. XColor xcolor = new XColor();
  2981. xcolor.red = (ushort)(backColor.R * 257);
  2982. xcolor.green = (ushort)(backColor.G * 257);
  2983. xcolor.blue = (ushort)(backColor.B * 257);
  2984. XAllocColor(DisplayHandle, DefaultColormap, ref xcolor);
  2985. pixel = (uint)xcolor.pixel.ToInt32();
  2986. gc_values = new XGCValues();
  2987. gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
  2988. gc_values.foreground = (IntPtr)pixel;
  2989. gc = XCreateGC(DisplayHandle, RootWindow, new IntPtr ((int) (GCFunction.GCSubwindowMode | GCFunction.GCForeground)), ref gc_values);
  2990. XSetForeground(DisplayHandle, gc, (UIntPtr)pixel);
  2991. XSetFunction(DisplayHandle, gc, GXFunction.GXxor);
  2992. return gc;
  2993. }
  2994. IntPtr GetReversibleControlGC (Control control, int line_width)
  2995. {
  2996. XGCValues gc_values;
  2997. IntPtr gc;
  2998. gc_values = new XGCValues();
  2999. gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
  3000. gc_values.line_width = line_width;
  3001. gc_values.foreground = XBlackPixel(DisplayHandle, ScreenNo);
  3002. // This logic will give us true rubber bands: (libsx, SANE_XOR)
  3003. //mask = foreground ^ background;
  3004. //XSetForeground(DisplayHandle, gc, 0xffffffff);
  3005. //XSetBackground(DisplayHandle, gc, background);
  3006. //XSetFunction(DisplayHandle, gc, GXxor);
  3007. //XSetPlaneMask(DisplayHandle, gc, mask);
  3008. gc = XCreateGC(DisplayHandle, control.Handle, new IntPtr ((int) (GCFunction.GCSubwindowMode | GCFunction.GCLineWidth | GCFunction.GCForeground)), ref gc_values);
  3009. uint foreground;
  3010. uint background;
  3011. XColor xcolor = new XColor();
  3012. xcolor.red = (ushort)(control.ForeColor.R * 257);
  3013. xcolor.green = (ushort)(control.ForeColor.G * 257);
  3014. xcolor.blue = (ushort)(control.ForeColor.B * 257);
  3015. XAllocColor(DisplayHandle, DefaultColormap, ref xcolor);
  3016. foreground = (uint)xcolor.pixel.ToInt32();
  3017. xcolor.red = (ushort)(control.BackColor.R * 257);
  3018. xcolor.green = (ushort)(control.BackColor.G * 257);
  3019. xcolor.blue = (ushort)(control.BackColor.B * 257);
  3020. XAllocColor(DisplayHandle, DefaultColormap, ref xcolor);
  3021. background = (uint)xcolor.pixel.ToInt32();
  3022. uint mask = foreground ^ background;
  3023. XSetForeground(DisplayHandle, gc, (UIntPtr)0xffffffff);
  3024. XSetBackground(DisplayHandle, gc, (UIntPtr)background);
  3025. XSetFunction(DisplayHandle, gc, GXFunction.GXxor);
  3026. XSetPlaneMask(DisplayHandle, gc, (IntPtr)mask);
  3027. return gc;
  3028. }
  3029. internal override void DrawReversibleLine(Point start, Point end, Color backColor)
  3030. {
  3031. if (backColor.GetBrightness() < 0.5)
  3032. backColor = Color.FromArgb(255 - backColor.R, 255 - backColor.G, 255 - backColor.B);
  3033. IntPtr gc = GetReversibleScreenGC (backColor);
  3034. XDrawLine (DisplayHandle, RootWindow, gc, start.X, start.Y, end.X, end.Y);
  3035. XFreeGC(DisplayHandle, gc);
  3036. }
  3037. internal override void DrawReversibleFrame (Rectangle rectangle, Color backColor, FrameStyle style)
  3038. {
  3039. if (backColor.GetBrightness() < 0.5)
  3040. backColor = Color.FromArgb(255 - backColor.R, 255 - backColor.G, 255 - backColor.B);
  3041. IntPtr gc = GetReversibleScreenGC (backColor);
  3042. if (rectangle.Width < 0) {
  3043. rectangle.X += rectangle.Width;
  3044. rectangle.Width = -rectangle.Width;
  3045. }
  3046. if (rectangle.Height < 0) {
  3047. rectangle.Y += rectangle.Height;
  3048. rectangle.Height = -rectangle.Height;
  3049. }
  3050. int line_width = 1;
  3051. GCLineStyle line_style = GCLineStyle.LineSolid;
  3052. GCCapStyle cap_style = GCCapStyle.CapButt;
  3053. GCJoinStyle join_style = GCJoinStyle.JoinMiter;
  3054. switch (style) {
  3055. case FrameStyle.Dashed:
  3056. line_style = GCLineStyle.LineOnOffDash;
  3057. break;
  3058. case FrameStyle.Thick:
  3059. line_width = 2;
  3060. break;
  3061. }
  3062. XSetLineAttributes (DisplayHandle, gc, line_width, line_style, cap_style, join_style);
  3063. XDrawRectangle(DisplayHandle, RootWindow, gc, rectangle.Left, rectangle.Top, rectangle.Width, rectangle.Height);
  3064. XFreeGC(DisplayHandle, gc);
  3065. }
  3066. internal override void FillReversibleRectangle (Rectangle rectangle, Color backColor)
  3067. {
  3068. if (backColor.GetBrightness() < 0.5)
  3069. backColor = Color.FromArgb(255 - backColor.R, 255 - backColor.G, 255 - backColor.B);
  3070. IntPtr gc = GetReversibleScreenGC (backColor);
  3071. if (rectangle.Width < 0) {
  3072. rectangle.X += rectangle.Width;
  3073. rectangle.Width = -rectangle.Width;
  3074. }
  3075. if (rectangle.Height < 0) {
  3076. rectangle.Y += rectangle.Height;
  3077. rectangle.Height = -rectangle.Height;
  3078. }
  3079. XFillRectangle(DisplayHandle, RootWindow, gc, rectangle.Left, rectangle.Top, rectangle.Width, rectangle.Height);
  3080. XFreeGC(DisplayHandle, gc);
  3081. }
  3082. internal override void DrawReversibleRectangle(IntPtr handle, Rectangle rect, int line_width)
  3083. {
  3084. IntPtr gc;
  3085. Control control = Control.FromHandle(handle);
  3086. gc = GetReversibleControlGC (control, line_width);
  3087. if ((rect.Width > 0) && (rect.Height > 0)) {
  3088. XDrawRectangle(DisplayHandle, control.Handle, gc, rect.Left, rect.Top, rect.Width, rect.Height);
  3089. } else {
  3090. if (rect.Width > 0) {
  3091. XDrawLine(DisplayHandle, control.Handle, gc, rect.X, rect.Y, rect.Right, rect.Y);
  3092. } else {
  3093. XDrawLine(DisplayHandle, control.Handle, gc, rect.X, rect.Y, rect.X, rect.Bottom);
  3094. }
  3095. }
  3096. XFreeGC(DisplayHandle, gc);
  3097. }
  3098. internal override void DoEvents()
  3099. {
  3100. DebugHelper.Enter ();
  3101. MSG msg = new MSG ();
  3102. XEventQueue queue;
  3103. if (OverrideCursorHandle != IntPtr.Zero) {
  3104. OverrideCursorHandle = IntPtr.Zero;
  3105. }
  3106. queue = ThreadQueue(Thread.CurrentThread);
  3107. queue.DispatchIdle = false;
  3108. in_doevents = true;
  3109. while (PeekMessage(queue, ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)) {
  3110. Message m = Message.Create (msg.hwnd, (int)msg.message, msg.wParam, msg.lParam);
  3111. if (Application.FilterMessage (ref m))
  3112. continue;
  3113. TranslateMessage (ref msg);
  3114. DispatchMessage (ref msg);
  3115. string key = msg.hwnd + ":" + msg.message;
  3116. if (messageHold[key] != null) {
  3117. messageHold[key] = ((int)messageHold[key]) - 1;
  3118. DebugHelper.WriteLine ("Got " + msg + " for " + key);
  3119. }
  3120. }
  3121. in_doevents = false;
  3122. queue.DispatchIdle = true;
  3123. DebugHelper.Leave ();
  3124. }
  3125. internal override void EnableWindow(IntPtr handle, bool Enable)
  3126. {
  3127. Hwnd hwnd;
  3128. hwnd = Hwnd.ObjectFromHandle(handle);
  3129. if (hwnd != null) {
  3130. hwnd.Enabled = Enable;
  3131. }
  3132. }
  3133. internal override void EndLoop(Thread thread)
  3134. {
  3135. // This is where we one day will shut down the loop for the thread
  3136. }
  3137. internal override IntPtr GetActive()
  3138. {
  3139. IntPtr actual_atom;
  3140. int actual_format;
  3141. IntPtr nitems;
  3142. IntPtr bytes_after;
  3143. IntPtr prop = IntPtr.Zero;
  3144. IntPtr active = IntPtr.Zero;
  3145. XGetWindowProperty(DisplayHandle, RootWindow, _NET_ACTIVE_WINDOW, IntPtr.Zero, new IntPtr (1), false, (IntPtr)Atom.XA_WINDOW, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
  3146. if (((long)nitems > 0) && (prop != IntPtr.Zero)) {
  3147. active = (IntPtr)Marshal.ReadInt32(prop);
  3148. XFree(prop);
  3149. } else {
  3150. // The window manager does not support _NET_ACTIVE_WINDOW. Fall back to XGetInputFocus.
  3151. IntPtr revert_to = IntPtr.Zero;
  3152. XGetInputFocus(DisplayHandle, out active, out revert_to);
  3153. }
  3154. if (active != IntPtr.Zero) {
  3155. Hwnd hwnd;
  3156. hwnd = Hwnd.GetObjectFromWindow(active);
  3157. if (hwnd != null) {
  3158. active = hwnd.Handle;
  3159. } else {
  3160. active = IntPtr.Zero;
  3161. }
  3162. }
  3163. return active;
  3164. }
  3165. internal override Region GetClipRegion(IntPtr handle)
  3166. {
  3167. Hwnd hwnd;
  3168. hwnd = Hwnd.ObjectFromHandle(handle);
  3169. if (hwnd != null) {
  3170. return hwnd.UserClip;
  3171. }
  3172. return null;
  3173. }
  3174. internal override void GetCursorInfo(IntPtr cursor, out int width, out int height, out int hotspot_x, out int hotspot_y)
  3175. {
  3176. width = 20;
  3177. height = 20;
  3178. hotspot_x = 0;
  3179. hotspot_y = 0;
  3180. }
  3181. internal override void GetDisplaySize(out Size size)
  3182. {
  3183. XWindowAttributes attributes=new XWindowAttributes();
  3184. lock (XlibLock) {
  3185. // FIXME - use _NET_WM messages instead?
  3186. XGetWindowAttributes(DisplayHandle, XRootWindow(DisplayHandle, 0), ref attributes);
  3187. }
  3188. size = new Size(attributes.width, attributes.height);
  3189. }
  3190. internal override SizeF GetAutoScaleSize(Font font)
  3191. {
  3192. Graphics g;
  3193. float width;
  3194. string magic_string = "The quick brown fox jumped over the lazy dog.";
  3195. double magic_number = 44.549996948242189;
  3196. g = Graphics.FromHwnd(FosterParent);
  3197. width = (float) (g.MeasureString (magic_string, font).Width / magic_number);
  3198. return new SizeF(width, font.Height);
  3199. }
  3200. internal override IntPtr GetParent(IntPtr handle)
  3201. {
  3202. Hwnd hwnd;
  3203. hwnd = Hwnd.ObjectFromHandle(handle);
  3204. if (hwnd != null && hwnd.parent != null) {
  3205. return hwnd.parent.Handle;
  3206. }
  3207. return IntPtr.Zero;
  3208. }
  3209. // This is a nop on win32 and x11
  3210. internal override IntPtr GetPreviousWindow(IntPtr handle)
  3211. {
  3212. return handle;
  3213. }
  3214. internal override void GetCursorPos(IntPtr handle, out int x, out int y)
  3215. {
  3216. IntPtr use_handle;
  3217. IntPtr root;
  3218. IntPtr child;
  3219. int root_x;
  3220. int root_y;
  3221. int win_x;
  3222. int win_y;
  3223. int keys_buttons;
  3224. if (handle != IntPtr.Zero) {
  3225. use_handle = Hwnd.ObjectFromHandle(handle).client_window;
  3226. } else {
  3227. use_handle = RootWindow;
  3228. }
  3229. lock (XlibLock) {
  3230. QueryPointer (DisplayHandle, use_handle, out root, out child, out root_x, out root_y, out win_x, out win_y, out keys_buttons);
  3231. }
  3232. if (handle != IntPtr.Zero) {
  3233. x = win_x;
  3234. y = win_y;
  3235. } else {
  3236. x = root_x;
  3237. y = root_y;
  3238. }
  3239. }
  3240. internal override IntPtr GetFocus()
  3241. {
  3242. return FocusWindow;
  3243. }
  3244. internal override bool GetFontMetrics(Graphics g, Font font, out int ascent, out int descent)
  3245. {
  3246. FontFamily ff = font.FontFamily;
  3247. ascent = ff.GetCellAscent (font.Style);
  3248. descent = ff.GetCellDescent (font.Style);
  3249. return true;
  3250. }
  3251. internal override Point GetMenuOrigin(IntPtr handle)
  3252. {
  3253. Hwnd hwnd;
  3254. hwnd = Hwnd.ObjectFromHandle(handle);
  3255. if (hwnd != null) {
  3256. return hwnd.MenuOrigin;
  3257. }
  3258. return Point.Empty;
  3259. }
  3260. [MonoTODO("Implement filtering")]
  3261. internal override bool GetMessage(Object queue_id, ref MSG msg, IntPtr handle, int wFilterMin, int wFilterMax)
  3262. {
  3263. XEvent xevent;
  3264. bool client;
  3265. Hwnd hwnd;
  3266. ProcessNextMessage:
  3267. if (((XEventQueue)queue_id).Count > 0) {
  3268. xevent = (XEvent) ((XEventQueue)queue_id).Dequeue ();
  3269. } else {
  3270. UpdateMessageQueue ((XEventQueue)queue_id);
  3271. if (((XEventQueue)queue_id).Count > 0) {
  3272. xevent = (XEvent) ((XEventQueue)queue_id).Dequeue ();
  3273. } else if (((XEventQueue)queue_id).Paint.Count > 0) {
  3274. xevent = ((XEventQueue)queue_id).Paint.Dequeue();
  3275. } else {
  3276. msg.hwnd= IntPtr.Zero;
  3277. msg.message = Msg.WM_ENTERIDLE;
  3278. return true;
  3279. }
  3280. }
  3281. hwnd = Hwnd.GetObjectFromWindow(xevent.AnyEvent.window);
  3282. #if DriverDebugDestroy
  3283. if (hwnd != null)
  3284. if (hwnd.zombie)
  3285. Console.WriteLine ( "GetMessage zombie, got Event: " + xevent.ToString () + " for 0x{0:x}", hwnd.Handle.ToInt32());
  3286. else
  3287. Console.WriteLine ( "GetMessage, got Event: " + xevent.ToString () + " for 0x{0:x}", hwnd.Handle.ToInt32());
  3288. #endif
  3289. // Handle messages for windows that are already or are about to be destroyed.
  3290. // we need a special block for this because unless we remove the hwnd from the paint
  3291. // queue it will always stay there (since we don't handle the expose), and we'll
  3292. // effectively loop infinitely trying to repaint a non-existant window.
  3293. if (hwnd != null && hwnd.zombie && xevent.type == XEventName.Expose) {
  3294. hwnd.expose_pending = hwnd.nc_expose_pending = false;
  3295. hwnd.Queue.Paint.Remove (hwnd);
  3296. goto ProcessNextMessage;
  3297. }
  3298. // We need to make sure we only allow DestroyNotify events through for zombie
  3299. // hwnds, since much of the event handling code makes requests using the hwnd's
  3300. // client_window, and that'll result in BadWindow errors if there's some lag
  3301. // between the XDestroyWindow call and the DestroyNotify event.
  3302. if (hwnd == null || hwnd.zombie && xevent.AnyEvent.type != XEventName.ClientMessage) {
  3303. DriverDebug("GetMessage(): Got message {0} for non-existent or already destroyed window {1:X}", xevent.type, xevent.AnyEvent.window.ToInt32());
  3304. goto ProcessNextMessage;
  3305. }
  3306. // If we get here, that means the window is no more but there are Client Messages
  3307. // to be processed, probably a Posted message (for instance, an WM_ACTIVATE message)
  3308. // We don't want anything else to run but the ClientMessage block, so reset all hwnd
  3309. // properties that might cause other processing to occur.
  3310. if (hwnd.zombie) {
  3311. hwnd.resizing_or_moving = false;
  3312. }
  3313. if (hwnd.client_window == xevent.AnyEvent.window) {
  3314. client = true;
  3315. //Console.WriteLine("Client message {1}, sending to window {0:X}", msg.hwnd.ToInt32(), xevent.type);
  3316. } else {
  3317. client = false;
  3318. //Console.WriteLine("Non-Client message, sending to window {0:X}", msg.hwnd.ToInt32());
  3319. }
  3320. msg.hwnd = hwnd.Handle;
  3321. // Windows sends WM_ENTERSIZEMOVE when a form resize/move operation starts and WM_EXITSIZEMOVE
  3322. // when it is done. The problem in X11 is that there is no concept of start-end of a moving/sizing.
  3323. // Configure events ("this window has resized/moved") are sent for each step of the resize. We send a
  3324. // WM_ENTERSIZEMOVE when we get the first Configure event. The problem is the WM_EXITSIZEMOVE.
  3325. //
  3326. // - There is no way for us to know which is the last Configure event. We can't traverse the events
  3327. // queue, because the next configure event might not be pending yet.
  3328. // - We can't get ButtonPress/Release events for the window decorations, because they are not part
  3329. // of the window(s) we manage.
  3330. // - We can't rely on the mouse state to change to "up" before the last Configure event. It doesn't.
  3331. //
  3332. // We are almost 100% guaranteed to get another event (e.g Expose or other), but we can't know for sure
  3333. // which, so we have here to check if the mouse buttons state is "up" and send the WM_EXITSIZEMOVE
  3334. //
  3335. if (hwnd.resizing_or_moving) {
  3336. int root_x, root_y, win_x, win_y, keys_buttons;
  3337. IntPtr root, child;
  3338. XQueryPointer (DisplayHandle, hwnd.Handle, out root, out child, out root_x, out root_y,
  3339. out win_x, out win_y, out keys_buttons);
  3340. if ((keys_buttons & (int)MouseKeyMasks.Button1Mask) == 0 &&
  3341. (keys_buttons & (int)MouseKeyMasks.Button2Mask) == 0 &&
  3342. (keys_buttons & (int)MouseKeyMasks.Button3Mask) == 0) {
  3343. hwnd.resizing_or_moving = false;
  3344. SendMessage (hwnd.Handle, Msg.WM_EXITSIZEMOVE, IntPtr.Zero, IntPtr.Zero);
  3345. }
  3346. }
  3347. //
  3348. // If you add a new event to this switch make sure to add it in
  3349. // UpdateMessage also unless it is not coming through the X event system.
  3350. //
  3351. switch(xevent.type) {
  3352. case XEventName.KeyPress: {
  3353. Keyboard.KeyEvent (FocusWindow, xevent, ref msg);
  3354. // F1 key special case - WM_HELP sending
  3355. if (msg.wParam == (IntPtr)VirtualKeys.VK_F1 || msg.wParam == (IntPtr)VirtualKeys.VK_HELP) {
  3356. // Send wM_HELP and then return it as a keypress message in
  3357. // case it needs to be preproccessed.
  3358. HELPINFO helpInfo = new HELPINFO ();
  3359. GetCursorPos (IntPtr.Zero, out helpInfo.MousePos.x, out helpInfo.MousePos.y);
  3360. IntPtr helpInfoPtr = Marshal.AllocHGlobal (Marshal.SizeOf (helpInfo));
  3361. Marshal.StructureToPtr (helpInfo, helpInfoPtr, true);
  3362. NativeWindow.WndProc (FocusWindow, Msg.WM_HELP, IntPtr.Zero, helpInfoPtr);
  3363. Marshal.FreeHGlobal (helpInfoPtr);
  3364. }
  3365. break;
  3366. }
  3367. case XEventName.KeyRelease: {
  3368. Keyboard.KeyEvent (FocusWindow, xevent, ref msg);
  3369. break;
  3370. }
  3371. case XEventName.ButtonPress: {
  3372. switch(xevent.ButtonEvent.button) {
  3373. case 1: {
  3374. MouseState |= MouseButtons.Left;
  3375. if (client) {
  3376. msg.message = Msg.WM_LBUTTONDOWN;
  3377. msg.wParam = GetMousewParam (0);
  3378. } else {
  3379. msg.message = Msg.WM_NCLBUTTONDOWN;
  3380. msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
  3381. MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
  3382. }
  3383. break;
  3384. }
  3385. case 2: {
  3386. MouseState |= MouseButtons.Middle;
  3387. if (client) {
  3388. msg.message = Msg.WM_MBUTTONDOWN;
  3389. msg.wParam = GetMousewParam (0);
  3390. } else {
  3391. msg.message = Msg.WM_NCMBUTTONDOWN;
  3392. msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
  3393. MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
  3394. }
  3395. break;
  3396. }
  3397. case 3: {
  3398. MouseState |= MouseButtons.Right;
  3399. if (client) {
  3400. msg.message = Msg.WM_RBUTTONDOWN;
  3401. msg.wParam = GetMousewParam (0);
  3402. } else {
  3403. msg.message = Msg.WM_NCRBUTTONDOWN;
  3404. msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
  3405. MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
  3406. }
  3407. break;
  3408. }
  3409. case 4: {
  3410. msg.hwnd = FocusWindow;
  3411. msg.message=Msg.WM_MOUSEWHEEL;
  3412. msg.wParam=GetMousewParam(120);
  3413. break;
  3414. }
  3415. case 5: {
  3416. msg.hwnd = FocusWindow;
  3417. msg.message=Msg.WM_MOUSEWHEEL;
  3418. msg.wParam=GetMousewParam(-120);
  3419. break;
  3420. }
  3421. }
  3422. msg.lParam=(IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
  3423. mouse_position.X = xevent.ButtonEvent.x;
  3424. mouse_position.Y = xevent.ButtonEvent.y;
  3425. if (!hwnd.Enabled) {
  3426. IntPtr dummy;
  3427. msg.hwnd = hwnd.EnabledHwnd;
  3428. 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);
  3429. msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
  3430. }
  3431. if (Grab.Hwnd != IntPtr.Zero) {
  3432. msg.hwnd = Grab.Hwnd;
  3433. }
  3434. if (ClickPending.Pending && ((((long)xevent.ButtonEvent.time - ClickPending.Time) < DoubleClickInterval) && (msg.wParam == ClickPending.wParam) && (msg.lParam == ClickPending.lParam) && (msg.message == ClickPending.Message))) {
  3435. // Looks like a genuine double click, clicked twice on the same spot with the same keys
  3436. switch(xevent.ButtonEvent.button) {
  3437. case 1: {
  3438. msg.message = client ? Msg.WM_LBUTTONDBLCLK : Msg.WM_NCLBUTTONDBLCLK;
  3439. break;
  3440. }
  3441. case 2: {
  3442. msg.message = client ? Msg.WM_MBUTTONDBLCLK : Msg.WM_NCMBUTTONDBLCLK;
  3443. break;
  3444. }
  3445. case 3: {
  3446. msg.message = client ? Msg.WM_RBUTTONDBLCLK : Msg.WM_NCRBUTTONDBLCLK;
  3447. break;
  3448. }
  3449. }
  3450. ClickPending.Pending = false;
  3451. } else {
  3452. ClickPending.Pending = true;
  3453. ClickPending.Hwnd = msg.hwnd;
  3454. ClickPending.Message = msg.message;
  3455. ClickPending.wParam = msg.wParam;
  3456. ClickPending.lParam = msg.lParam;
  3457. ClickPending.Time = (long)xevent.ButtonEvent.time;
  3458. }
  3459. if (msg.message == Msg.WM_LBUTTONDOWN || msg.message == Msg.WM_MBUTTONDOWN || msg.message == Msg.WM_RBUTTONDOWN) {
  3460. SendParentNotify(msg.hwnd, msg.message, mouse_position.X, mouse_position.Y);
  3461. }
  3462. break;
  3463. }
  3464. case XEventName.ButtonRelease: {
  3465. switch(xevent.ButtonEvent.button) {
  3466. case 1: {
  3467. if (client) {
  3468. msg.message = Msg.WM_LBUTTONUP;
  3469. } else {
  3470. msg.message = Msg.WM_NCLBUTTONUP;
  3471. msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
  3472. MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
  3473. }
  3474. MouseState &= ~MouseButtons.Left;
  3475. msg.wParam = GetMousewParam (0);
  3476. break;
  3477. }
  3478. case 2: {
  3479. if (client) {
  3480. msg.message = Msg.WM_MBUTTONUP;
  3481. } else {
  3482. msg.message = Msg.WM_NCMBUTTONUP;
  3483. msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
  3484. MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
  3485. }
  3486. MouseState &= ~MouseButtons.Middle;
  3487. msg.wParam = GetMousewParam (0);
  3488. break;
  3489. }
  3490. case 3: {
  3491. if (client) {
  3492. msg.message = Msg.WM_RBUTTONUP;
  3493. } else {
  3494. msg.message = Msg.WM_NCRBUTTONUP;
  3495. msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
  3496. MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
  3497. }
  3498. MouseState &= ~MouseButtons.Right;
  3499. msg.wParam = GetMousewParam (0);
  3500. break;
  3501. }
  3502. case 4: {
  3503. goto ProcessNextMessage;
  3504. }
  3505. case 5: {
  3506. goto ProcessNextMessage;
  3507. }
  3508. }
  3509. if (!hwnd.Enabled) {
  3510. IntPtr dummy;
  3511. msg.hwnd = hwnd.EnabledHwnd;
  3512. 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);
  3513. msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
  3514. }
  3515. if (Grab.Hwnd != IntPtr.Zero) {
  3516. msg.hwnd = Grab.Hwnd;
  3517. }
  3518. msg.lParam=(IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
  3519. mouse_position.X = xevent.ButtonEvent.x;
  3520. mouse_position.Y = xevent.ButtonEvent.y;
  3521. // Win32 splurts MouseMove events all over the place, regardless of whether the mouse is actually moving or
  3522. // not, especially after mousedown and mouseup. To support apps relying on mousemove events between and after
  3523. // mouse clicks to repaint or whatever, we generate a mousemove event here. *sigh*
  3524. if (msg.message == Msg.WM_LBUTTONUP || msg.message == Msg.WM_MBUTTONUP || msg.message == Msg.WM_RBUTTONUP) {
  3525. XEvent motionEvent = new XEvent ();
  3526. motionEvent.type = XEventName.MotionNotify;
  3527. motionEvent.MotionEvent.display = DisplayHandle;
  3528. motionEvent.MotionEvent.window = xevent.ButtonEvent.window;
  3529. motionEvent.MotionEvent.x = xevent.ButtonEvent.x;
  3530. motionEvent.MotionEvent.y = xevent.ButtonEvent.y;
  3531. hwnd.Queue.EnqueueLocked (motionEvent);
  3532. }
  3533. break;
  3534. }
  3535. case XEventName.MotionNotify: {
  3536. if (client) {
  3537. DriverDebug("GetMessage(): Window {0:X} MotionNotify x={1} y={2}",
  3538. client ? hwnd.client_window.ToInt32() : hwnd.whole_window.ToInt32(),
  3539. xevent.MotionEvent.x, xevent.MotionEvent.y);
  3540. if (Grab.Hwnd != IntPtr.Zero) {
  3541. msg.hwnd = Grab.Hwnd;
  3542. } else {
  3543. if (hwnd.Enabled) {
  3544. NativeWindow.WndProc(msg.hwnd, Msg.WM_SETCURSOR, msg.hwnd, (IntPtr)HitTest.HTCLIENT);
  3545. }
  3546. }
  3547. if (xevent.MotionEvent.is_hint != 0)
  3548. {
  3549. IntPtr root, child;
  3550. int mask;
  3551. XQueryPointer (DisplayHandle, xevent.AnyEvent.window,
  3552. out root, out child,
  3553. out xevent.MotionEvent.x_root,
  3554. out xevent.MotionEvent.y_root,
  3555. out xevent.MotionEvent.x,
  3556. out xevent.MotionEvent.y, out mask);
  3557. }
  3558. msg.message = Msg.WM_MOUSEMOVE;
  3559. msg.wParam = GetMousewParam(0);
  3560. msg.lParam = (IntPtr) (xevent.MotionEvent.y << 16 | xevent.MotionEvent.x & 0xFFFF);
  3561. if (!hwnd.Enabled) {
  3562. IntPtr dummy;
  3563. msg.hwnd = hwnd.EnabledHwnd;
  3564. 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);
  3565. msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
  3566. }
  3567. mouse_position.X = xevent.MotionEvent.x;
  3568. mouse_position.Y = xevent.MotionEvent.y;
  3569. if ((HoverState.Timer.Enabled) &&
  3570. (((mouse_position.X + HoverState.Size.Width) < HoverState.X) ||
  3571. ((mouse_position.X - HoverState.Size.Width) > HoverState.X) ||
  3572. ((mouse_position.Y + HoverState.Size.Height) < HoverState.Y) ||
  3573. ((mouse_position.Y - HoverState.Size.Height) > HoverState.Y))) {
  3574. HoverState.Timer.Stop();
  3575. HoverState.Timer.Start();
  3576. HoverState.X = mouse_position.X;
  3577. HoverState.Y = mouse_position.Y;
  3578. }
  3579. break;
  3580. } else {
  3581. HitTest ht;
  3582. IntPtr dummy;
  3583. DriverDebug("GetMessage(): non-client area {0:X} MotionNotify x={1} y={2}",
  3584. client ? hwnd.client_window.ToInt32() : hwnd.whole_window.ToInt32(),
  3585. xevent.MotionEvent.x, xevent.MotionEvent.y);
  3586. msg.message = Msg.WM_NCMOUSEMOVE;
  3587. if (!hwnd.Enabled) {
  3588. msg.hwnd = hwnd.EnabledHwnd;
  3589. 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);
  3590. msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
  3591. }
  3592. ht = NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
  3593. NativeWindow.WndProc(hwnd.client_window, Msg.WM_SETCURSOR, msg.hwnd, (IntPtr)ht);
  3594. mouse_position.X = xevent.MotionEvent.x;
  3595. mouse_position.Y = xevent.MotionEvent.y;
  3596. }
  3597. break;
  3598. }
  3599. case XEventName.EnterNotify: {
  3600. if (!hwnd.Enabled) {
  3601. goto ProcessNextMessage;
  3602. }
  3603. if (xevent.CrossingEvent.mode == NotifyMode.NotifyGrab || xevent.AnyEvent.window != hwnd.client_window) {
  3604. goto ProcessNextMessage;
  3605. }
  3606. if (xevent.CrossingEvent.mode == NotifyMode.NotifyUngrab) { // Pseudo motion caused by grabbing
  3607. if (LastPointerWindow == xevent.AnyEvent.window)
  3608. goto ProcessNextMessage;
  3609. if (LastPointerWindow != IntPtr.Zero) {
  3610. Point enter_loc = new Point (xevent.ButtonEvent.x, xevent.ButtonEvent.y);
  3611. // We need this due to EnterNotify being fired on all the parent controls
  3612. // of the Control being grabbed, and obviously in that scenario we are not
  3613. // actuallty entering them
  3614. Control ctrl = Control.FromHandle (hwnd.client_window);
  3615. foreach (Control child_control in ctrl.Controls.GetAllControls ())
  3616. if (child_control.Bounds.Contains (enter_loc))
  3617. goto ProcessNextMessage;
  3618. // A MouseLeave/LeaveNotify event is sent to the previous window
  3619. // until the mouse is ungrabbed, not when actually leaving its bounds
  3620. int x = xevent.CrossingEvent.x_root;
  3621. int y = xevent.CrossingEvent.y_root;
  3622. ScreenToClient (LastPointerWindow, ref x, ref y);
  3623. XEvent leaveEvent = new XEvent ();
  3624. leaveEvent.type = XEventName.LeaveNotify;
  3625. leaveEvent.CrossingEvent.display = DisplayHandle;
  3626. leaveEvent.CrossingEvent.window = LastPointerWindow;
  3627. leaveEvent.CrossingEvent.x = x;
  3628. leaveEvent.CrossingEvent.y = y;
  3629. leaveEvent.CrossingEvent.mode = NotifyMode.NotifyNormal;
  3630. Hwnd last_pointer_hwnd = Hwnd.ObjectFromHandle (LastPointerWindow);
  3631. last_pointer_hwnd.Queue.EnqueueLocked (leaveEvent);
  3632. }
  3633. }
  3634. LastPointerWindow = xevent.AnyEvent.window;
  3635. msg.message = Msg.WM_MOUSE_ENTER;
  3636. HoverState.X = xevent.CrossingEvent.x;
  3637. HoverState.Y = xevent.CrossingEvent.y;
  3638. HoverState.Timer.Enabled = true;
  3639. HoverState.Window = xevent.CrossingEvent.window;
  3640. // Win32 sends a WM_MOUSEMOVE after mouse enter
  3641. XEvent motionEvent = new XEvent ();
  3642. motionEvent.type = XEventName.MotionNotify;
  3643. motionEvent.MotionEvent.display = DisplayHandle;
  3644. motionEvent.MotionEvent.window = xevent.ButtonEvent.window;
  3645. motionEvent.MotionEvent.x = xevent.ButtonEvent.x;
  3646. motionEvent.MotionEvent.y = xevent.ButtonEvent.y;
  3647. hwnd.Queue.EnqueueLocked (motionEvent);
  3648. break;
  3649. }
  3650. case XEventName.LeaveNotify: {
  3651. if (xevent.CrossingEvent.mode == NotifyMode.NotifyUngrab) {
  3652. WindowUngrabbed (hwnd.Handle);
  3653. goto ProcessNextMessage;
  3654. }
  3655. if (!hwnd.Enabled) {
  3656. goto ProcessNextMessage;
  3657. }
  3658. if ((xevent.CrossingEvent.mode != NotifyMode.NotifyNormal) || (xevent.CrossingEvent.window != hwnd.client_window)) {
  3659. goto ProcessNextMessage;
  3660. }
  3661. // If a grab is taking place, ignore it - we handle it in EnterNotify
  3662. if (Grab.Hwnd != IntPtr.Zero)
  3663. goto ProcessNextMessage;
  3664. // Reset the cursor explicitly on X11.
  3665. // X11 remembers the last set cursor for the window and in cases where
  3666. // the control won't get a WM_SETCURSOR X11 will restore the last
  3667. // known cursor, which we don't want.
  3668. //
  3669. SetCursor (hwnd.client_window, IntPtr.Zero);
  3670. msg.message=Msg.WM_MOUSELEAVE;
  3671. HoverState.Timer.Enabled = false;
  3672. HoverState.Window = IntPtr.Zero;
  3673. break;
  3674. }
  3675. #if later
  3676. case XEventName.CreateNotify: {
  3677. if (client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {
  3678. msg.message = WM_CREATE;
  3679. // Set up CreateStruct
  3680. } else {
  3681. goto ProcessNextMessage;
  3682. }
  3683. break;
  3684. }
  3685. #endif
  3686. case XEventName.ReparentNotify: {
  3687. if (hwnd.parent == null) { // Toplevel
  3688. if ((xevent.ReparentEvent.parent != IntPtr.Zero) && (xevent.ReparentEvent.window == hwnd.whole_window)) {
  3689. hwnd.Reparented = true;
  3690. // The location given by the event is not reliable between different wm's,
  3691. // so use an alternative way of getting it.
  3692. Point location = GetTopLevelWindowLocation (hwnd);
  3693. hwnd.X = location.X;
  3694. hwnd.Y = location.Y;
  3695. if (hwnd.opacity != 0xffffffff) {
  3696. IntPtr opacity;
  3697. opacity = (IntPtr)(Int32)hwnd.opacity;
  3698. XChangeProperty(DisplayHandle, XGetParent(hwnd.whole_window), _NET_WM_WINDOW_OPACITY, (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, ref opacity, 1);
  3699. }
  3700. SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, msg.wParam, msg.lParam);
  3701. goto ProcessNextMessage;
  3702. } else {
  3703. hwnd.Reparented = false;
  3704. goto ProcessNextMessage;
  3705. }
  3706. }
  3707. goto ProcessNextMessage;
  3708. }
  3709. case XEventName.ConfigureNotify: {
  3710. if (!client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) { // Ignore events for children (SubstructureNotify) and client areas
  3711. DriverDebug("GetMessage(): Window {0:X} ConfigureNotify x={1} y={2} width={3} height={4}",
  3712. hwnd.client_window.ToInt32(), xevent.ConfigureEvent.x,
  3713. xevent.ConfigureEvent.y, xevent.ConfigureEvent.width, xevent.ConfigureEvent.height);
  3714. lock (hwnd.configure_lock) {
  3715. Form form = Control.FromHandle (hwnd.client_window) as Form;
  3716. if (form != null && !hwnd.resizing_or_moving) {
  3717. if (hwnd.x != form.Bounds.X || hwnd.y != form.Bounds.Y) {
  3718. SendMessage (form.Handle, Msg.WM_SYSCOMMAND, (IntPtr)SystemCommands.SC_MOVE, IntPtr.Zero);
  3719. hwnd.resizing_or_moving = true;
  3720. } else if (hwnd.width != form.Bounds.Width || hwnd.height != form.Bounds.Height) {
  3721. SendMessage (form.Handle, Msg.WM_SYSCOMMAND, (IntPtr)SystemCommands.SC_SIZE, IntPtr.Zero);
  3722. hwnd.resizing_or_moving = true;
  3723. }
  3724. if (hwnd.resizing_or_moving)
  3725. SendMessage (form.Handle, Msg.WM_ENTERSIZEMOVE, IntPtr.Zero, IntPtr.Zero);
  3726. }
  3727. SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
  3728. hwnd.configure_pending = false;
  3729. // We need to adjust our client window to track the resize of whole_window
  3730. if (hwnd.whole_window != hwnd.client_window)
  3731. PerformNCCalc(hwnd);
  3732. }
  3733. }
  3734. goto ProcessNextMessage;
  3735. }
  3736. case XEventName.FocusIn: {
  3737. // We received focus. We use X11 focus only to know if the app window does or does not have focus
  3738. // We do not track the actual focussed window via it. Instead, this is done via FocusWindow internally
  3739. // Receiving focus means we've gotten activated and therefore we need to let the actual FocusWindow know
  3740. // about it having focus again
  3741. if (xevent.FocusChangeEvent.detail != NotifyDetail.NotifyNonlinear) {
  3742. goto ProcessNextMessage;
  3743. }
  3744. if (FocusWindow == IntPtr.Zero) {
  3745. Control c = Control.FromHandle (hwnd.client_window);
  3746. if (c == null)
  3747. goto ProcessNextMessage;
  3748. Form form = c.FindForm ();
  3749. if (form == null)
  3750. goto ProcessNextMessage;
  3751. if (ActiveWindow != form.Handle) {
  3752. ActiveWindow = form.Handle;
  3753. SendMessage (ActiveWindow, Msg.WM_ACTIVATE, (IntPtr) WindowActiveFlags.WA_ACTIVE, IntPtr.Zero);
  3754. }
  3755. goto ProcessNextMessage;
  3756. }
  3757. Keyboard.FocusIn (FocusWindow);
  3758. SendMessage(FocusWindow, Msg.WM_SETFOCUS, IntPtr.Zero, IntPtr.Zero);
  3759. goto ProcessNextMessage;
  3760. }
  3761. case XEventName.FocusOut: {
  3762. // Se the comment for our FocusIn handler
  3763. if (xevent.FocusChangeEvent.detail != NotifyDetail.NotifyNonlinear) {
  3764. goto ProcessNextMessage;
  3765. }
  3766. while (Keyboard.ResetKeyState(FocusWindow, ref msg)) {
  3767. SendMessage(FocusWindow, msg.message, msg.wParam, msg.lParam);
  3768. }
  3769. Keyboard.FocusOut(hwnd.client_window);
  3770. SendMessage(FocusWindow, Msg.WM_KILLFOCUS, IntPtr.Zero, IntPtr.Zero);
  3771. goto ProcessNextMessage;
  3772. }
  3773. // We are already firing WM_SHOWWINDOW messages in the proper places, but I'm leaving this code
  3774. // in case we break a scenario not taken into account in the tests
  3775. case XEventName.MapNotify: {
  3776. /*if (client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) { // Ignore events for children (SubstructureNotify) and client areas
  3777. hwnd.mapped = true;
  3778. msg.message = Msg.WM_SHOWWINDOW;
  3779. msg.wParam = (IntPtr) 1;
  3780. // XXX we're missing the lParam..
  3781. break;
  3782. }*/
  3783. goto ProcessNextMessage;
  3784. }
  3785. case XEventName.UnmapNotify: {
  3786. /*if (client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) { // Ignore events for children (SubstructureNotify) and client areas
  3787. hwnd.mapped = false;
  3788. msg.message = Msg.WM_SHOWWINDOW;
  3789. msg.wParam = (IntPtr) 0;
  3790. // XXX we're missing the lParam..
  3791. break;
  3792. }*/
  3793. goto ProcessNextMessage;
  3794. }
  3795. case XEventName.Expose: {
  3796. if (!hwnd.Mapped) {
  3797. if (client) {
  3798. hwnd.expose_pending = false;
  3799. } else {
  3800. hwnd.nc_expose_pending = false;
  3801. }
  3802. goto ProcessNextMessage;
  3803. }
  3804. if (client) {
  3805. if (!hwnd.expose_pending) {
  3806. goto ProcessNextMessage;
  3807. }
  3808. } else {
  3809. if (!hwnd.nc_expose_pending) {
  3810. goto ProcessNextMessage;
  3811. }
  3812. switch (hwnd.border_style) {
  3813. case FormBorderStyle.Fixed3D: {
  3814. Graphics g;
  3815. g = Graphics.FromHwnd(hwnd.whole_window);
  3816. if (hwnd.border_static)
  3817. ControlPaint.DrawBorder3D(g, new Rectangle(0, 0, hwnd.Width, hwnd.Height), Border3DStyle.SunkenOuter);
  3818. else
  3819. ControlPaint.DrawBorder3D(g, new Rectangle(0, 0, hwnd.Width, hwnd.Height), Border3DStyle.Sunken);
  3820. g.Dispose();
  3821. break;
  3822. }
  3823. case FormBorderStyle.FixedSingle: {
  3824. Graphics g;
  3825. g = Graphics.FromHwnd(hwnd.whole_window);
  3826. ControlPaint.DrawBorder(g, new Rectangle(0, 0, hwnd.Width, hwnd.Height), Color.Black, ButtonBorderStyle.Solid);
  3827. g.Dispose();
  3828. break;
  3829. }
  3830. }
  3831. DriverDebug("GetMessage(): Window {0:X} Exposed non-client area {1},{2} {3}x{4}",
  3832. hwnd.client_window.ToInt32(), xevent.ExposeEvent.x, xevent.ExposeEvent.y,
  3833. xevent.ExposeEvent.width, xevent.ExposeEvent.height);
  3834. Rectangle rect = new Rectangle (xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
  3835. Region region = new Region (rect);
  3836. IntPtr hrgn = region.GetHrgn (null); // Graphics object isn't needed
  3837. msg.message = Msg.WM_NCPAINT;
  3838. msg.wParam = hrgn == IntPtr.Zero ? (IntPtr)1 : hrgn;
  3839. msg.refobject = region;
  3840. break;
  3841. }
  3842. DriverDebug("GetMessage(): Window {0:X} Exposed area {1},{2} {3}x{4}",
  3843. hwnd.client_window.ToInt32(), xevent.ExposeEvent.x, xevent.ExposeEvent.y,
  3844. xevent.ExposeEvent.width, xevent.ExposeEvent.height);
  3845. if (Caret.Visible == true) {
  3846. Caret.Paused = true;
  3847. HideCaret();
  3848. }
  3849. if (Caret.Visible == true) {
  3850. ShowCaret();
  3851. Caret.Paused = false;
  3852. }
  3853. msg.message = Msg.WM_PAINT;
  3854. break;
  3855. }
  3856. case XEventName.DestroyNotify: {
  3857. // This is a bit tricky, we don't receive our own DestroyNotify, we only get those for our children
  3858. hwnd = Hwnd.ObjectFromHandle(xevent.DestroyWindowEvent.window);
  3859. // We may get multiple for the same window, act only one the first (when Hwnd still knows about it)
  3860. if ((hwnd != null) && (hwnd.client_window == xevent.DestroyWindowEvent.window)) {
  3861. CleanupCachedWindows (hwnd);
  3862. DriverDebug("Received X11 Destroy Notification for {0}", XplatUI.Window(hwnd.client_window));
  3863. msg.hwnd = hwnd.client_window;
  3864. msg.message=Msg.WM_DESTROY;
  3865. hwnd.Dispose();
  3866. } else {
  3867. goto ProcessNextMessage;
  3868. }
  3869. break;
  3870. }
  3871. case XEventName.ClientMessage: {
  3872. if (Dnd.HandleClientMessage (ref xevent)) {
  3873. goto ProcessNextMessage;
  3874. }
  3875. if (xevent.ClientMessageEvent.message_type == AsyncAtom) {
  3876. XplatUIDriverSupport.ExecuteClientMessage((GCHandle)xevent.ClientMessageEvent.ptr1);
  3877. goto ProcessNextMessage;
  3878. }
  3879. if (xevent.ClientMessageEvent.message_type == HoverState.Atom) {
  3880. msg.message = Msg.WM_MOUSEHOVER;
  3881. msg.wParam = GetMousewParam(0);
  3882. msg.lParam = (IntPtr) (xevent.ClientMessageEvent.ptr1);
  3883. return true;
  3884. }
  3885. if (xevent.ClientMessageEvent.message_type == (IntPtr)PostAtom) {
  3886. DebugHelper.Indent ();
  3887. DebugHelper.WriteLine (String.Format ("Posted message:" + (Msg) xevent.ClientMessageEvent.ptr2.ToInt32 () + " for 0x{0:x}", xevent.ClientMessageEvent.ptr1.ToInt32 ()));
  3888. DebugHelper.Unindent ();
  3889. msg.hwnd = xevent.ClientMessageEvent.ptr1;
  3890. msg.message = (Msg) xevent.ClientMessageEvent.ptr2.ToInt32 ();
  3891. msg.wParam = xevent.ClientMessageEvent.ptr3;
  3892. msg.lParam = xevent.ClientMessageEvent.ptr4;
  3893. if (msg.message == (Msg)Msg.WM_QUIT)
  3894. return false;
  3895. else
  3896. return true;
  3897. }
  3898. if (xevent.ClientMessageEvent.message_type == _XEMBED) {
  3899. #if DriverDebugXEmbed
  3900. Console.WriteLine("GOT EMBED MESSAGE {0:X}, detail {1:X}", xevent.ClientMessageEvent.ptr2.ToInt32(), xevent.ClientMessageEvent.ptr3.ToInt32());
  3901. #endif
  3902. if (xevent.ClientMessageEvent.ptr2.ToInt32() == (int)XEmbedMessage.EmbeddedNotify) {
  3903. XSizeHints hints = new XSizeHints();
  3904. IntPtr dummy;
  3905. XGetWMNormalHints(DisplayHandle, hwnd.whole_window, ref hints, out dummy);
  3906. hwnd.width = hints.max_width;
  3907. hwnd.height = hints.max_height;
  3908. hwnd.ClientRect = Rectangle.Empty;
  3909. SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
  3910. }
  3911. }
  3912. if (xevent.ClientMessageEvent.message_type == WM_PROTOCOLS) {
  3913. if (xevent.ClientMessageEvent.ptr1 == WM_DELETE_WINDOW) {
  3914. SendMessage (msg.hwnd, Msg.WM_SYSCOMMAND, (IntPtr)SystemCommands.SC_CLOSE, IntPtr.Zero);
  3915. msg.message = Msg.WM_CLOSE;
  3916. return true;
  3917. }
  3918. // We should not get this, but I'll leave the code in case we need it in the future
  3919. if (xevent.ClientMessageEvent.ptr1 == WM_TAKE_FOCUS) {
  3920. goto ProcessNextMessage;
  3921. }
  3922. }
  3923. goto ProcessNextMessage;
  3924. }
  3925. default: {
  3926. goto ProcessNextMessage;
  3927. }
  3928. }
  3929. return true;
  3930. }
  3931. HitTest NCHitTest (Hwnd hwnd, int x, int y)
  3932. {
  3933. // The hit test is sent in screen coordinates
  3934. IntPtr dummy;
  3935. int screen_x, screen_y;
  3936. XTranslateCoordinates (DisplayHandle, hwnd.WholeWindow, RootWindow, x, y, out screen_x, out screen_y, out dummy);
  3937. return (HitTest) NativeWindow.WndProc (hwnd.client_window, Msg.WM_NCHITTEST, IntPtr.Zero,
  3938. (IntPtr) (screen_y << 16 | screen_x & 0xFFFF));
  3939. }
  3940. // Our very basic implementation of MoveResize - we can extend it later
  3941. // *if* needed
  3942. internal override void BeginMoveResize (IntPtr handle)
  3943. {
  3944. // We *need* to ungrab the pointer in the current display
  3945. XplatUI.UngrabWindow (Grab.Hwnd);
  3946. int x_root, y_root;
  3947. GetCursorPos (IntPtr.Zero, out x_root, out y_root);
  3948. Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
  3949. SendNetWMMessage (hwnd.whole_window, _NET_WM_MOVERESIZE, (IntPtr) x_root, (IntPtr) y_root,
  3950. (IntPtr) NetWmMoveResize._NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT,
  3951. (IntPtr) 1); // left button
  3952. }
  3953. internal override bool GetText(IntPtr handle, out string text)
  3954. {
  3955. lock (XlibLock) {
  3956. IntPtr actual_atom;
  3957. int actual_format;
  3958. IntPtr nitems;
  3959. IntPtr bytes_after;
  3960. IntPtr prop = IntPtr.Zero;
  3961. XGetWindowProperty(DisplayHandle, handle,
  3962. _NET_WM_NAME, IntPtr.Zero, new IntPtr (1), false,
  3963. UTF8_STRING, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
  3964. if ((long)nitems > 0 && prop != IntPtr.Zero) {
  3965. text = Marshal.PtrToStringUni (prop, (int)nitems);
  3966. XFree (prop);
  3967. return true;
  3968. }
  3969. else {
  3970. // fallback on the non-_NET property
  3971. IntPtr textptr;
  3972. textptr = IntPtr.Zero;
  3973. XFetchName(DisplayHandle, Hwnd.ObjectFromHandle(handle).whole_window, ref textptr);
  3974. if (textptr != IntPtr.Zero) {
  3975. text = Marshal.PtrToStringAnsi(textptr);
  3976. XFree(textptr);
  3977. return true;
  3978. } else {
  3979. text = "";
  3980. return false;
  3981. }
  3982. }
  3983. }
  3984. }
  3985. 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)
  3986. {
  3987. Hwnd hwnd;
  3988. hwnd = Hwnd.ObjectFromHandle(handle);
  3989. if (hwnd != null) {
  3990. x = hwnd.x;
  3991. y = hwnd.y;
  3992. width = hwnd.width;
  3993. height = hwnd.height;
  3994. PerformNCCalc(hwnd);
  3995. client_width = hwnd.ClientRect.Width;
  3996. client_height = hwnd.ClientRect.Height;
  3997. return;
  3998. }
  3999. // Should we throw an exception or fail silently?
  4000. // throw new ArgumentException("Called with an invalid window handle", "handle");
  4001. x = 0;
  4002. y = 0;
  4003. width = 0;
  4004. height = 0;
  4005. client_width = 0;
  4006. client_height = 0;
  4007. }
  4008. internal override FormWindowState GetWindowState(IntPtr handle)
  4009. {
  4010. Hwnd hwnd;
  4011. hwnd = Hwnd.ObjectFromHandle(handle);
  4012. if (hwnd.cached_window_state == (FormWindowState)(-1))
  4013. hwnd.cached_window_state = UpdateWindowState (handle);
  4014. return hwnd.cached_window_state;
  4015. }
  4016. FormWindowState UpdateWindowState (IntPtr handle) {
  4017. IntPtr actual_atom;
  4018. int actual_format;
  4019. IntPtr nitems;
  4020. IntPtr bytes_after;
  4021. IntPtr prop = IntPtr.Zero;
  4022. IntPtr atom;
  4023. int maximized;
  4024. bool minimized;
  4025. XWindowAttributes attributes;
  4026. Hwnd hwnd;
  4027. hwnd = Hwnd.ObjectFromHandle(handle);
  4028. maximized = 0;
  4029. minimized = false;
  4030. XGetWindowProperty(DisplayHandle, hwnd.whole_window, _NET_WM_STATE, IntPtr.Zero, new IntPtr (256), false, (IntPtr)Atom.XA_ATOM, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
  4031. if (((long)nitems > 0) && (prop != IntPtr.Zero)) {
  4032. for (int i = 0; i < (long)nitems; i++) {
  4033. atom = (IntPtr)Marshal.ReadInt32(prop, i * 4);
  4034. if ((atom == _NET_WM_STATE_MAXIMIZED_HORZ) || (atom == _NET_WM_STATE_MAXIMIZED_VERT)) {
  4035. maximized++;
  4036. } else if (atom == _NET_WM_STATE_HIDDEN) {
  4037. minimized = true;
  4038. }
  4039. }
  4040. XFree(prop);
  4041. }
  4042. if (minimized) {
  4043. return FormWindowState.Minimized;
  4044. } else if (maximized == 2) {
  4045. return FormWindowState.Maximized;
  4046. }
  4047. attributes = new XWindowAttributes();
  4048. XGetWindowAttributes(DisplayHandle, hwnd.client_window, ref attributes);
  4049. if (attributes.map_state == MapState.IsUnmapped) {
  4050. return (FormWindowState)(-1);
  4051. }
  4052. return FormWindowState.Normal;
  4053. }
  4054. internal override void GrabInfo(out IntPtr handle, out bool GrabConfined, out Rectangle GrabArea)
  4055. {
  4056. handle = Grab.Hwnd;
  4057. GrabConfined = Grab.Confined;
  4058. GrabArea = Grab.Area;
  4059. }
  4060. internal override void GrabWindow(IntPtr handle, IntPtr confine_to_handle)
  4061. {
  4062. Hwnd hwnd;
  4063. IntPtr confine_to_window;
  4064. confine_to_window = IntPtr.Zero;
  4065. if (confine_to_handle != IntPtr.Zero) {
  4066. XWindowAttributes attributes = new XWindowAttributes();
  4067. hwnd = Hwnd.ObjectFromHandle(confine_to_handle);
  4068. lock (XlibLock) {
  4069. XGetWindowAttributes(DisplayHandle, hwnd.client_window, ref attributes);
  4070. }
  4071. Grab.Area.X = attributes.x;
  4072. Grab.Area.Y = attributes.y;
  4073. Grab.Area.Width = attributes.width;
  4074. Grab.Area.Height = attributes.height;
  4075. Grab.Confined = true;
  4076. confine_to_window = hwnd.client_window;
  4077. }
  4078. Grab.Hwnd = handle;
  4079. hwnd = Hwnd.ObjectFromHandle(handle);
  4080. lock (XlibLock) {
  4081. XGrabPointer(DisplayHandle, hwnd.client_window, false,
  4082. EventMask.ButtonPressMask | EventMask.ButtonMotionMask |
  4083. EventMask.ButtonReleaseMask | EventMask.PointerMotionMask |
  4084. EventMask.PointerMotionHintMask | EventMask.LeaveWindowMask,
  4085. GrabMode.GrabModeAsync, GrabMode.GrabModeAsync, confine_to_window, IntPtr.Zero, IntPtr.Zero);
  4086. }
  4087. }
  4088. internal override void UngrabWindow(IntPtr hwnd)
  4089. {
  4090. lock (XlibLock) {
  4091. XUngrabPointer(DisplayHandle, IntPtr.Zero);
  4092. XFlush(DisplayHandle);
  4093. }
  4094. WindowUngrabbed (hwnd);
  4095. }
  4096. void WindowUngrabbed (IntPtr hwnd) {
  4097. bool was_grabbed = Grab.Hwnd != IntPtr.Zero;
  4098. Grab.Hwnd = IntPtr.Zero;
  4099. Grab.Confined = false;
  4100. if (was_grabbed) {
  4101. // lparam should be the handle to the window gaining the mouse capture,
  4102. // but X doesn't seem to give us that information.
  4103. // Also only generate WM_CAPTURECHANGED if the window actually was grabbed.
  4104. // X will send a NotifyUngrab, but since it comes late sometimes we're
  4105. // calling WindowUngrabbed directly from UngrabWindow in order to send
  4106. // this WM right away.
  4107. SendMessage (hwnd, Msg.WM_CAPTURECHANGED, IntPtr.Zero, IntPtr.Zero);
  4108. }
  4109. }
  4110. internal override void HandleException(Exception e)
  4111. {
  4112. StackTrace st = new StackTrace(e, true);
  4113. Console.WriteLine("Exception '{0}'", e.Message+st.ToString());
  4114. Console.WriteLine("{0}{1}", e.Message, st.ToString());
  4115. }
  4116. internal override void Invalidate(IntPtr handle, Rectangle rc, bool clear)
  4117. {
  4118. Hwnd hwnd;
  4119. hwnd = Hwnd.ObjectFromHandle(handle);
  4120. if (clear) {
  4121. AddExpose (hwnd, true, hwnd.X, hwnd.Y, hwnd.Width, hwnd.Height);
  4122. } else {
  4123. AddExpose (hwnd, true, rc.X, rc.Y, rc.Width, rc.Height);
  4124. }
  4125. }
  4126. internal override void InvalidateNC (IntPtr handle)
  4127. {
  4128. Hwnd hwnd;
  4129. hwnd = Hwnd.ObjectFromHandle(handle);
  4130. AddExpose (hwnd, hwnd.WholeWindow == hwnd.ClientWindow, 0, 0, hwnd.Width, hwnd.Height);
  4131. }
  4132. internal override bool IsEnabled(IntPtr handle)
  4133. {
  4134. Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
  4135. return (hwnd != null && hwnd.Enabled);
  4136. }
  4137. internal override bool IsVisible(IntPtr handle)
  4138. {
  4139. Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
  4140. return (hwnd != null && hwnd.visible);
  4141. }
  4142. internal override void KillTimer(Timer timer)
  4143. {
  4144. XEventQueue queue = (XEventQueue) MessageQueues [timer.thread];
  4145. if (queue == null) {
  4146. // This isn't really an error, MS doesn't start the timer if
  4147. // it has no assosciated queue. In this case, remove the timer
  4148. // from the list of unattached timers (if it was enabled).
  4149. lock (unattached_timer_list) {
  4150. if (unattached_timer_list.Contains (timer))
  4151. unattached_timer_list.Remove (timer);
  4152. }
  4153. return;
  4154. }
  4155. queue.timer_list.Remove (timer);
  4156. }
  4157. internal override void MenuToScreen(IntPtr handle, ref int x, ref int y)
  4158. {
  4159. int dest_x_return;
  4160. int dest_y_return;
  4161. IntPtr child;
  4162. Hwnd hwnd;
  4163. hwnd = Hwnd.ObjectFromHandle(handle);
  4164. lock (XlibLock) {
  4165. XTranslateCoordinates(DisplayHandle, hwnd.whole_window, RootWindow, x, y, out dest_x_return, out dest_y_return, out child);
  4166. }
  4167. x = dest_x_return;
  4168. y = dest_y_return;
  4169. }
  4170. internal override void OverrideCursor(IntPtr cursor)
  4171. {
  4172. if (Grab.Hwnd != IntPtr.Zero) {
  4173. XChangeActivePointerGrab (DisplayHandle,
  4174. EventMask.ButtonMotionMask |
  4175. EventMask.PointerMotionMask |
  4176. EventMask.PointerMotionHintMask |
  4177. EventMask.ButtonPressMask |
  4178. EventMask.ButtonReleaseMask,
  4179. cursor, IntPtr.Zero);
  4180. return;
  4181. }
  4182. OverrideCursorHandle = cursor;
  4183. }
  4184. internal override PaintEventArgs PaintEventStart(ref Message msg, IntPtr handle, bool client)
  4185. {
  4186. PaintEventArgs paint_event;
  4187. Hwnd hwnd;
  4188. Hwnd paint_hwnd;
  4189. //
  4190. // handle (and paint_hwnd) refers to the window that is should be painted.
  4191. // msg.HWnd (and hwnd) refers to the window that got the paint message.
  4192. //
  4193. hwnd = Hwnd.ObjectFromHandle(msg.HWnd);
  4194. if (msg.HWnd == handle) {
  4195. paint_hwnd = hwnd;
  4196. } else {
  4197. paint_hwnd = Hwnd.ObjectFromHandle (handle);
  4198. }
  4199. if (Caret.Visible == true) {
  4200. Caret.Paused = true;
  4201. HideCaret();
  4202. }
  4203. Graphics dc;
  4204. if (client) {
  4205. dc = Graphics.FromHwnd (paint_hwnd.client_window);
  4206. Region clip_region = new Region ();
  4207. clip_region.MakeEmpty();
  4208. foreach (Rectangle r in hwnd.ClipRectangles) {
  4209. /* Expand the region slightly.
  4210. * See bug 464464.
  4211. */
  4212. Rectangle r2 = Rectangle.FromLTRB (r.Left, r.Top, r.Right, r.Bottom + 1);
  4213. clip_region.Union (r2);
  4214. }
  4215. if (hwnd.UserClip != null) {
  4216. clip_region.Intersect(hwnd.UserClip);
  4217. }
  4218. dc.Clip = clip_region;
  4219. paint_event = new PaintEventArgs(dc, hwnd.Invalid);
  4220. hwnd.expose_pending = false;
  4221. hwnd.ClearInvalidArea();
  4222. hwnd.drawing_stack.Push (paint_event);
  4223. hwnd.drawing_stack.Push (dc);
  4224. return paint_event;
  4225. } else {
  4226. dc = Graphics.FromHwnd (paint_hwnd.whole_window);
  4227. if (!hwnd.nc_invalid.IsEmpty) {
  4228. dc.SetClip (hwnd.nc_invalid);
  4229. paint_event = new PaintEventArgs(dc, hwnd.nc_invalid);
  4230. } else {
  4231. paint_event = new PaintEventArgs(dc, new Rectangle(0, 0, hwnd.width, hwnd.height));
  4232. }
  4233. hwnd.nc_expose_pending = false;
  4234. hwnd.ClearNcInvalidArea ();
  4235. hwnd.drawing_stack.Push (paint_event);
  4236. hwnd.drawing_stack.Push (dc);
  4237. return paint_event;
  4238. }
  4239. }
  4240. internal override void PaintEventEnd(ref Message msg, IntPtr handle, bool client)
  4241. {
  4242. Hwnd hwnd;
  4243. hwnd = Hwnd.ObjectFromHandle (msg.HWnd);
  4244. Graphics dc = (Graphics)hwnd.drawing_stack.Pop ();
  4245. dc.Flush();
  4246. dc.Dispose();
  4247. PaintEventArgs pe = (PaintEventArgs)hwnd.drawing_stack.Pop();
  4248. pe.SetGraphics (null);
  4249. pe.Dispose ();
  4250. if (Caret.Visible == true) {
  4251. ShowCaret();
  4252. Caret.Paused = false;
  4253. }
  4254. }
  4255. [MonoTODO("Implement filtering and PM_NOREMOVE")]
  4256. internal override bool PeekMessage(Object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags)
  4257. {
  4258. XEventQueue queue = (XEventQueue) queue_id;
  4259. bool pending;
  4260. if ((flags & (uint)PeekMessageFlags.PM_REMOVE) == 0) {
  4261. throw new NotImplementedException("PeekMessage PM_NOREMOVE is not implemented yet"); // FIXME - Implement PM_NOREMOVE flag
  4262. }
  4263. pending = false;
  4264. if (queue.Count > 0) {
  4265. pending = true;
  4266. } else {
  4267. // Only call UpdateMessageQueue if real events are pending
  4268. // otherwise we go to sleep on the socket
  4269. if (XPending(DisplayHandle) != 0) {
  4270. UpdateMessageQueue((XEventQueue)queue_id);
  4271. pending = true;
  4272. } else if (((XEventQueue)queue_id).Paint.Count > 0) {
  4273. pending = true;
  4274. }
  4275. }
  4276. CheckTimers(queue.timer_list, DateTime.UtcNow);
  4277. if (!pending) {
  4278. return false;
  4279. }
  4280. return GetMessage(queue_id, ref msg, hWnd, wFilterMin, wFilterMax);
  4281. }
  4282. internal override bool PostMessage (IntPtr handle, Msg message, IntPtr wparam, IntPtr lparam)
  4283. {
  4284. XEvent xevent = new XEvent ();
  4285. Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
  4286. xevent.type = XEventName.ClientMessage;
  4287. xevent.ClientMessageEvent.display = DisplayHandle;
  4288. if (hwnd != null) {
  4289. xevent.ClientMessageEvent.window = hwnd.whole_window;
  4290. } else {
  4291. xevent.ClientMessageEvent.window = IntPtr.Zero;
  4292. }
  4293. xevent.ClientMessageEvent.message_type = (IntPtr) PostAtom;
  4294. xevent.ClientMessageEvent.format = 32;
  4295. xevent.ClientMessageEvent.ptr1 = handle;
  4296. xevent.ClientMessageEvent.ptr2 = (IntPtr) message;
  4297. xevent.ClientMessageEvent.ptr3 = wparam;
  4298. xevent.ClientMessageEvent.ptr4 = lparam;
  4299. if (hwnd != null)
  4300. hwnd.Queue.EnqueueLocked (xevent);
  4301. else
  4302. ThreadQueue(Thread.CurrentThread).EnqueueLocked (xevent);
  4303. return true;
  4304. }
  4305. internal override void PostQuitMessage(int exitCode)
  4306. {
  4307. ApplicationContext ctx = Application.MWFThread.Current.Context;
  4308. Form f = ctx != null ? ctx.MainForm : null;
  4309. if (f != null)
  4310. PostMessage (Application.MWFThread.Current.Context.MainForm.window.Handle, Msg.WM_QUIT, IntPtr.Zero, IntPtr.Zero);
  4311. else
  4312. PostMessage (FosterParent, Msg.WM_QUIT, IntPtr.Zero, IntPtr.Zero);
  4313. XFlush(DisplayHandle);
  4314. }
  4315. internal override void RequestAdditionalWM_NCMessages(IntPtr hwnd, bool hover, bool leave)
  4316. {
  4317. // TODO
  4318. }
  4319. internal override void RequestNCRecalc(IntPtr handle)
  4320. {
  4321. Hwnd hwnd;
  4322. hwnd = Hwnd.ObjectFromHandle(handle);
  4323. if (hwnd == null) {
  4324. return;
  4325. }
  4326. PerformNCCalc(hwnd);
  4327. SendMessage(handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
  4328. InvalidateNC(handle);
  4329. }
  4330. internal override void ResetMouseHover(IntPtr handle)
  4331. {
  4332. Hwnd hwnd;
  4333. hwnd = Hwnd.ObjectFromHandle(handle);
  4334. if (hwnd == null) {
  4335. return;
  4336. }
  4337. HoverState.Timer.Enabled = true;
  4338. HoverState.X = mouse_position.X;
  4339. HoverState.Y = mouse_position.Y;
  4340. HoverState.Window = handle;
  4341. }
  4342. internal override void ScreenToClient(IntPtr handle, ref int x, ref int y)
  4343. {
  4344. int dest_x_return;
  4345. int dest_y_return;
  4346. IntPtr child;
  4347. Hwnd hwnd;
  4348. hwnd = Hwnd.ObjectFromHandle(handle);
  4349. lock (XlibLock) {
  4350. XTranslateCoordinates (DisplayHandle, RootWindow, hwnd.client_window, x, y, out dest_x_return, out dest_y_return, out child);
  4351. }
  4352. x = dest_x_return;
  4353. y = dest_y_return;
  4354. }
  4355. internal override void ScreenToMenu(IntPtr handle, ref int x, ref int y)
  4356. {
  4357. int dest_x_return;
  4358. int dest_y_return;
  4359. IntPtr child;
  4360. Hwnd hwnd;
  4361. hwnd = Hwnd.ObjectFromHandle(handle);
  4362. lock (XlibLock) {
  4363. XTranslateCoordinates (DisplayHandle, RootWindow, hwnd.whole_window, x, y, out dest_x_return, out dest_y_return, out child);
  4364. }
  4365. Form form = Control.FromHandle (handle) as Form;
  4366. if (form != null && form.window_manager != null) {
  4367. dest_y_return -= form.window_manager.TitleBarHeight;
  4368. }
  4369. x = dest_x_return;
  4370. y = dest_y_return;
  4371. }
  4372. bool GraphicsExposePredicate (IntPtr display, ref XEvent xevent, IntPtr arg)
  4373. {
  4374. return (xevent.type == XEventName.GraphicsExpose || xevent.type == XEventName.NoExpose) &&
  4375. arg == xevent.GraphicsExposeEvent.drawable;
  4376. }
  4377. delegate bool EventPredicate (IntPtr display, ref XEvent xevent, IntPtr arg);
  4378. void ProcessGraphicsExpose (Hwnd hwnd)
  4379. {
  4380. XEvent xevent = new XEvent ();
  4381. IntPtr handle = Hwnd.HandleFromObject (hwnd);
  4382. EventPredicate predicate = GraphicsExposePredicate;
  4383. for (;;) {
  4384. XIfEvent (Display, ref xevent, predicate, handle);
  4385. if (xevent.type != XEventName.GraphicsExpose)
  4386. break;
  4387. AddExpose (hwnd, xevent.ExposeEvent.window == hwnd.ClientWindow, xevent.GraphicsExposeEvent.x, xevent.GraphicsExposeEvent.y,
  4388. xevent.GraphicsExposeEvent.width, xevent.GraphicsExposeEvent.height);
  4389. if (xevent.GraphicsExposeEvent.count == 0)
  4390. break;
  4391. }
  4392. }
  4393. internal override void ScrollWindow(IntPtr handle, Rectangle area, int XAmount, int YAmount, bool with_children)
  4394. {
  4395. Hwnd hwnd;
  4396. IntPtr gc;
  4397. XGCValues gc_values;
  4398. hwnd = Hwnd.ObjectFromHandle(handle);
  4399. Rectangle r = Rectangle.Intersect (hwnd.Invalid, area);
  4400. if (!r.IsEmpty) {
  4401. /* We have an invalid area in the window we're scrolling.
  4402. Adjust our stored invalid rectangle to to match the scrolled amount */
  4403. r.X += XAmount;
  4404. r.Y += YAmount;
  4405. if (r.X < 0) {
  4406. r.Width += r.X;
  4407. r.X =0;
  4408. }
  4409. if (r.Y < 0) {
  4410. r.Height += r.Y;
  4411. r.Y =0;
  4412. }
  4413. if (area.Contains (hwnd.Invalid))
  4414. hwnd.ClearInvalidArea ();
  4415. hwnd.AddInvalidArea(r);
  4416. }
  4417. gc_values = new XGCValues();
  4418. if (with_children) {
  4419. gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
  4420. }
  4421. gc = XCreateGC(DisplayHandle, hwnd.client_window, IntPtr.Zero, ref gc_values);
  4422. Rectangle visible_rect = GetTotalVisibleArea (hwnd.client_window);
  4423. visible_rect.Intersect (area);
  4424. Rectangle dest_rect = visible_rect;
  4425. dest_rect.Y += YAmount;
  4426. dest_rect.X += XAmount;
  4427. dest_rect.Intersect (area);
  4428. Point src = new Point (dest_rect.X - XAmount, dest_rect.Y - YAmount);
  4429. XCopyArea (DisplayHandle, hwnd.client_window, hwnd.client_window, gc, src.X, src.Y,
  4430. dest_rect.Width, dest_rect.Height, dest_rect.X, dest_rect.Y);
  4431. Rectangle dirty_area = GetDirtyArea (area, dest_rect, XAmount, YAmount);
  4432. AddExpose (hwnd, true, dirty_area.X, dirty_area.Y, dirty_area.Width, dirty_area.Height);
  4433. ProcessGraphicsExpose (hwnd);
  4434. XFreeGC(DisplayHandle, gc);
  4435. }
  4436. internal override void ScrollWindow(IntPtr handle, int XAmount, int YAmount, bool with_children)
  4437. {
  4438. Hwnd hwnd;
  4439. Rectangle rect;
  4440. hwnd = Hwnd.GetObjectFromWindow(handle);
  4441. rect = hwnd.ClientRect;
  4442. rect.X = 0;
  4443. rect.Y = 0;
  4444. ScrollWindow(handle, rect, XAmount, YAmount, with_children);
  4445. }
  4446. Rectangle GetDirtyArea (Rectangle total_area, Rectangle valid_area, int XAmount, int YAmount)
  4447. {
  4448. Rectangle dirty_area = total_area;
  4449. if (YAmount > 0)
  4450. dirty_area.Height -= valid_area.Height;
  4451. else if (YAmount < 0) {
  4452. dirty_area.Height -= valid_area.Height;
  4453. dirty_area.Y += valid_area.Height;
  4454. }
  4455. if (XAmount > 0)
  4456. dirty_area.Width -= valid_area.Width;
  4457. else if (XAmount < 0) {
  4458. dirty_area.Width -= valid_area.Width;
  4459. dirty_area.X += valid_area.Width;
  4460. }
  4461. return dirty_area;
  4462. }
  4463. Rectangle GetTotalVisibleArea (IntPtr handle)
  4464. {
  4465. Control c = Control.FromHandle (handle);
  4466. Rectangle visible_area = c.ClientRectangle;
  4467. visible_area.Location = c.PointToScreen (Point.Empty);
  4468. for (Control parent = c.Parent; parent != null; parent = parent.Parent) {
  4469. if (!parent.IsHandleCreated || !parent.Visible)
  4470. return visible_area; // Non visible, not need to finish computations
  4471. Rectangle r = parent.ClientRectangle;
  4472. r.Location = parent.PointToScreen (Point.Empty);
  4473. visible_area.Intersect (r);
  4474. }
  4475. visible_area.Location = c.PointToClient (visible_area.Location);
  4476. return visible_area;
  4477. }
  4478. internal override void SendAsyncMethod (AsyncMethodData method)
  4479. {
  4480. Hwnd hwnd;
  4481. XEvent xevent = new XEvent ();
  4482. hwnd = Hwnd.ObjectFromHandle(method.Handle);
  4483. xevent.type = XEventName.ClientMessage;
  4484. xevent.ClientMessageEvent.display = DisplayHandle;
  4485. xevent.ClientMessageEvent.window = method.Handle;
  4486. xevent.ClientMessageEvent.message_type = (IntPtr)AsyncAtom;
  4487. xevent.ClientMessageEvent.format = 32;
  4488. xevent.ClientMessageEvent.ptr1 = (IntPtr) GCHandle.Alloc (method);
  4489. hwnd.Queue.EnqueueLocked (xevent);
  4490. WakeupMain ();
  4491. }
  4492. delegate IntPtr WndProcDelegate (IntPtr hwnd, Msg message, IntPtr wParam, IntPtr lParam);
  4493. internal override IntPtr SendMessage (IntPtr hwnd, Msg message, IntPtr wParam, IntPtr lParam)
  4494. {
  4495. Hwnd h;
  4496. h = Hwnd.ObjectFromHandle(hwnd);
  4497. if (h != null && h.queue != ThreadQueue (Thread.CurrentThread)) {
  4498. AsyncMethodResult result;
  4499. AsyncMethodData data;
  4500. result = new AsyncMethodResult ();
  4501. data = new AsyncMethodData ();
  4502. data.Handle = hwnd;
  4503. data.Method = new WndProcDelegate (NativeWindow.WndProc);
  4504. data.Args = new object[] { hwnd, message, wParam, lParam };
  4505. data.Result = result;
  4506. SendAsyncMethod (data);
  4507. DriverDebug("Sending {0} message across.", message);
  4508. return IntPtr.Zero;
  4509. }
  4510. string key = hwnd + ":" + message;
  4511. if (messageHold[key] != null)
  4512. messageHold[key] = ((int)messageHold[key]) - 1;
  4513. return NativeWindow.WndProc(hwnd, message, wParam, lParam);
  4514. }
  4515. internal override int SendInput(IntPtr handle, Queue keys)
  4516. {
  4517. if (handle == IntPtr.Zero)
  4518. return 0;
  4519. int count = keys.Count;
  4520. Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
  4521. while (keys.Count > 0) {
  4522. MSG msg = (MSG)keys.Dequeue();
  4523. XEvent xevent = new XEvent ();
  4524. xevent.type = (msg.message == Msg.WM_KEYUP ? XEventName.KeyRelease : XEventName.KeyPress);
  4525. xevent.KeyEvent.display = DisplayHandle;
  4526. if (hwnd != null) {
  4527. xevent.KeyEvent.window = hwnd.whole_window;
  4528. } else {
  4529. xevent.KeyEvent.window = IntPtr.Zero;
  4530. }
  4531. xevent.KeyEvent.keycode = Keyboard.ToKeycode((int)msg.wParam);
  4532. hwnd.Queue.EnqueueLocked (xevent);
  4533. }
  4534. return count;
  4535. }
  4536. internal override void SetAllowDrop (IntPtr handle, bool value)
  4537. {
  4538. // We allow drop on all windows
  4539. }
  4540. internal override DragDropEffects StartDrag (IntPtr handle, object data,
  4541. DragDropEffects allowed_effects)
  4542. {
  4543. Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
  4544. if (hwnd == null)
  4545. throw new ArgumentException ("Attempt to begin drag from invalid window handle (" + handle.ToInt32 () + ").");
  4546. return Dnd.StartDrag (hwnd.client_window, data, allowed_effects);
  4547. }
  4548. internal override void SetBorderStyle(IntPtr handle, FormBorderStyle border_style)
  4549. {
  4550. Form form = Control.FromHandle (handle) as Form;
  4551. if (form != null && form.window_manager == null) {
  4552. CreateParams cp = form.GetCreateParams ();
  4553. if (border_style == FormBorderStyle.FixedToolWindow ||
  4554. border_style == FormBorderStyle.SizableToolWindow ||
  4555. cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW)) {
  4556. form.window_manager = new ToolWindowManager (form);
  4557. }
  4558. }
  4559. RequestNCRecalc(handle);
  4560. }
  4561. internal override void SetCaretPos(IntPtr handle, int x, int y)
  4562. {
  4563. if (Caret.Hwnd == handle) {
  4564. Caret.Timer.Stop();
  4565. HideCaret();
  4566. Caret.X = x;
  4567. Caret.Y = y;
  4568. Keyboard.SetCaretPos (Caret, handle, x, y);
  4569. if (Caret.Visible == true) {
  4570. ShowCaret();
  4571. Caret.Timer.Start();
  4572. }
  4573. }
  4574. }
  4575. internal override void SetClipRegion(IntPtr handle, Region region)
  4576. {
  4577. Hwnd hwnd;
  4578. hwnd = Hwnd.ObjectFromHandle(handle);
  4579. if (hwnd == null) {
  4580. return;
  4581. }
  4582. hwnd.UserClip = region;
  4583. }
  4584. internal override void SetCursor(IntPtr handle, IntPtr cursor)
  4585. {
  4586. Hwnd hwnd;
  4587. if (OverrideCursorHandle == IntPtr.Zero) {
  4588. if ((LastCursorWindow == handle) && (LastCursorHandle == cursor)) {
  4589. return;
  4590. }
  4591. LastCursorHandle = cursor;
  4592. LastCursorWindow = handle;
  4593. hwnd = Hwnd.ObjectFromHandle(handle);
  4594. lock (XlibLock) {
  4595. if (cursor != IntPtr.Zero) {
  4596. XDefineCursor(DisplayHandle, hwnd.whole_window, cursor);
  4597. } else {
  4598. XUndefineCursor(DisplayHandle, hwnd.whole_window);
  4599. }
  4600. XFlush(DisplayHandle);
  4601. }
  4602. return;
  4603. }
  4604. hwnd = Hwnd.ObjectFromHandle(handle);
  4605. lock (XlibLock) {
  4606. XDefineCursor(DisplayHandle, hwnd.whole_window, OverrideCursorHandle);
  4607. }
  4608. }
  4609. void QueryPointer (IntPtr display, IntPtr w, out IntPtr root, out IntPtr child,
  4610. out int root_x, out int root_y, out int child_x, out int child_y,
  4611. out int mask)
  4612. {
  4613. /* this code was written with the help of
  4614. glance at gdk. I never would have realized we
  4615. needed a loop in order to traverse down in the
  4616. hierarchy. I would have assumed you'd get the
  4617. most deeply nested child and have to do
  4618. XQueryTree to move back up the hierarchy..
  4619. stupid me, of course. */
  4620. IntPtr c;
  4621. XGrabServer (display);
  4622. XQueryPointer(display, w, out root, out c,
  4623. out root_x, out root_y, out child_x, out child_y,
  4624. out mask);
  4625. if (root != w)
  4626. c = root;
  4627. IntPtr child_last = IntPtr.Zero;
  4628. while (c != IntPtr.Zero) {
  4629. child_last = c;
  4630. XQueryPointer(display, c, out root, out c,
  4631. out root_x, out root_y, out child_x, out child_y,
  4632. out mask);
  4633. }
  4634. XUngrabServer (display);
  4635. XFlush (display);
  4636. child = child_last;
  4637. }
  4638. internal override void SetCursorPos(IntPtr handle, int x, int y)
  4639. {
  4640. if (handle == IntPtr.Zero) {
  4641. lock (XlibLock) {
  4642. IntPtr root, child;
  4643. int root_x, root_y, child_x, child_y, mask;
  4644. /* we need to do a
  4645. * QueryPointer before warping
  4646. * because if the warp is on
  4647. * the RootWindow, the x/y are
  4648. * relative to the current
  4649. * mouse position
  4650. */
  4651. QueryPointer (DisplayHandle, RootWindow,
  4652. out root,
  4653. out child,
  4654. out root_x, out root_y,
  4655. out child_x, out child_y,
  4656. out mask);
  4657. XWarpPointer(DisplayHandle, IntPtr.Zero, IntPtr.Zero, 0, 0, 0, 0, x - root_x, y - root_y);
  4658. XFlush (DisplayHandle);
  4659. /* then we need to a
  4660. * QueryPointer after warping
  4661. * to manually generate a
  4662. * motion event for the window
  4663. * we move into.
  4664. */
  4665. QueryPointer (DisplayHandle, RootWindow,
  4666. out root,
  4667. out child,
  4668. out root_x, out root_y,
  4669. out child_x, out child_y,
  4670. out mask);
  4671. Hwnd child_hwnd = Hwnd.ObjectFromHandle(child);
  4672. if (child_hwnd == null) {
  4673. return;
  4674. }
  4675. XEvent xevent = new XEvent ();
  4676. xevent.type = XEventName.MotionNotify;
  4677. xevent.MotionEvent.display = DisplayHandle;
  4678. xevent.MotionEvent.window = child_hwnd.client_window;
  4679. xevent.MotionEvent.root = RootWindow;
  4680. xevent.MotionEvent.x = child_x;
  4681. xevent.MotionEvent.y = child_y;
  4682. xevent.MotionEvent.x_root = root_x;
  4683. xevent.MotionEvent.y_root = root_y;
  4684. xevent.MotionEvent.state = mask;
  4685. child_hwnd.Queue.EnqueueLocked (xevent);
  4686. }
  4687. } else {
  4688. Hwnd hwnd;
  4689. hwnd = Hwnd.ObjectFromHandle(handle);
  4690. lock (XlibLock) {
  4691. XWarpPointer(DisplayHandle, IntPtr.Zero, hwnd.client_window, 0, 0, 0, 0, x, y);
  4692. }
  4693. }
  4694. }
  4695. internal override void SetFocus(IntPtr handle)
  4696. {
  4697. Hwnd hwnd;
  4698. IntPtr prev_focus_window;
  4699. hwnd = Hwnd.ObjectFromHandle(handle);
  4700. if (hwnd.client_window == FocusWindow) {
  4701. return;
  4702. }
  4703. // Win32 doesn't do anything if disabled
  4704. if (!hwnd.enabled)
  4705. return;
  4706. prev_focus_window = FocusWindow;
  4707. FocusWindow = hwnd.client_window;
  4708. if (prev_focus_window != IntPtr.Zero) {
  4709. SendMessage(prev_focus_window, Msg.WM_KILLFOCUS, FocusWindow, IntPtr.Zero);
  4710. }
  4711. Keyboard.FocusIn (FocusWindow);
  4712. SendMessage(FocusWindow, Msg.WM_SETFOCUS, prev_focus_window, IntPtr.Zero);
  4713. //XSetInputFocus(DisplayHandle, Hwnd.ObjectFromHandle(handle).client_window, RevertTo.None, IntPtr.Zero);
  4714. }
  4715. internal override void SetIcon(IntPtr handle, Icon icon)
  4716. {
  4717. Hwnd hwnd;
  4718. hwnd = Hwnd.ObjectFromHandle(handle);
  4719. if (hwnd != null) {
  4720. SetIcon(hwnd, icon);
  4721. }
  4722. }
  4723. internal override void SetMenu(IntPtr handle, Menu menu)
  4724. {
  4725. Hwnd hwnd;
  4726. hwnd = Hwnd.ObjectFromHandle(handle);
  4727. hwnd.menu = menu;
  4728. RequestNCRecalc(handle);
  4729. }
  4730. internal override void SetModal(IntPtr handle, bool Modal)
  4731. {
  4732. if (Modal) {
  4733. ModalWindows.Push(handle);
  4734. } else {
  4735. if (ModalWindows.Contains(handle)) {
  4736. ModalWindows.Pop();
  4737. }
  4738. if (ModalWindows.Count > 0) {
  4739. Activate((IntPtr)ModalWindows.Peek());
  4740. }
  4741. }
  4742. Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
  4743. Control ctrl = Control.FromHandle (handle);
  4744. SetWMStyles (hwnd, ctrl.GetCreateParams ());
  4745. }
  4746. internal override IntPtr SetParent(IntPtr handle, IntPtr parent)
  4747. {
  4748. Hwnd hwnd;
  4749. hwnd = Hwnd.ObjectFromHandle(handle);
  4750. hwnd.parent = Hwnd.ObjectFromHandle(parent);
  4751. lock (XlibLock) {
  4752. DriverDebug("Parent for window {0} = {1}", XplatUI.Window(hwnd.Handle), XplatUI.Window(hwnd.parent != null ? hwnd.parent.Handle : IntPtr.Zero));
  4753. XReparentWindow(DisplayHandle, hwnd.whole_window, hwnd.parent == null ? FosterParent : hwnd.parent.client_window, hwnd.x, hwnd.y);
  4754. }
  4755. return IntPtr.Zero;
  4756. }
  4757. internal override void SetTimer (Timer timer)
  4758. {
  4759. XEventQueue queue = (XEventQueue) MessageQueues [timer.thread];
  4760. if (queue == null) {
  4761. // This isn't really an error, MS doesn't start the timer if
  4762. // it has no assosciated queue at this stage (it will be
  4763. // enabled when a window is activated).
  4764. unattached_timer_list.Add (timer);
  4765. return;
  4766. }
  4767. queue.timer_list.Add (timer);
  4768. WakeupMain ();
  4769. }
  4770. internal override bool SetTopmost(IntPtr handle, bool enabled)
  4771. {
  4772. Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
  4773. if (enabled) {
  4774. lock (XlibLock) {
  4775. if (hwnd.Mapped) {
  4776. SendNetWMMessage(hwnd.WholeWindow, _NET_WM_STATE, (IntPtr) NetWmStateRequest._NET_WM_STATE_ADD, _NET_WM_STATE_ABOVE, IntPtr.Zero);
  4777. } else {
  4778. int[] atoms = new int[8];
  4779. atoms[0] = _NET_WM_STATE_ABOVE.ToInt32();
  4780. XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_STATE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
  4781. }
  4782. }
  4783. } else {
  4784. lock (XlibLock) {
  4785. if (hwnd.Mapped)
  4786. SendNetWMMessage(hwnd.WholeWindow, _NET_WM_STATE, (IntPtr) NetWmStateRequest._NET_WM_STATE_REMOVE, _NET_WM_STATE_ABOVE, IntPtr.Zero);
  4787. else
  4788. XDeleteProperty(DisplayHandle, hwnd.whole_window, _NET_WM_STATE);
  4789. }
  4790. }
  4791. return true;
  4792. }
  4793. internal override bool SetOwner(IntPtr handle, IntPtr handle_owner)
  4794. {
  4795. Hwnd hwnd;
  4796. Hwnd hwnd_owner;
  4797. hwnd = Hwnd.ObjectFromHandle(handle);
  4798. if (handle_owner != IntPtr.Zero) {
  4799. hwnd_owner = Hwnd.ObjectFromHandle(handle_owner);
  4800. lock (XlibLock) {
  4801. int[] atoms;
  4802. atoms = new int[8];
  4803. atoms[0] = _NET_WM_WINDOW_TYPE_NORMAL.ToInt32();
  4804. XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_WINDOW_TYPE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
  4805. if (hwnd_owner != null) {
  4806. XSetTransientForHint(DisplayHandle, hwnd.whole_window, hwnd_owner.whole_window);
  4807. } else {
  4808. XSetTransientForHint(DisplayHandle, hwnd.whole_window, RootWindow);
  4809. }
  4810. }
  4811. } else {
  4812. lock (XlibLock) {
  4813. XDeleteProperty(DisplayHandle, hwnd.whole_window, (IntPtr)Atom.XA_WM_TRANSIENT_FOR);
  4814. }
  4815. }
  4816. return true;
  4817. }
  4818. internal override bool SetVisible (IntPtr handle, bool visible, bool activate)
  4819. {
  4820. Hwnd hwnd;
  4821. hwnd = Hwnd.ObjectFromHandle(handle);
  4822. hwnd.visible = visible;
  4823. lock (XlibLock) {
  4824. if (visible) {
  4825. MapWindow(hwnd, WindowType.Both);
  4826. if (Control.FromHandle(handle) is Form) {
  4827. FormWindowState s;
  4828. s = ((Form)Control.FromHandle(handle)).WindowState;
  4829. switch(s) {
  4830. case FormWindowState.Minimized: SetWindowState(handle, FormWindowState.Minimized); break;
  4831. case FormWindowState.Maximized: SetWindowState(handle, FormWindowState.Maximized); break;
  4832. }
  4833. }
  4834. SendMessage(handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
  4835. }
  4836. else {
  4837. UnmapWindow(hwnd, WindowType.Both);
  4838. }
  4839. }
  4840. return true;
  4841. }
  4842. internal override void SetWindowMinMax(IntPtr handle, Rectangle maximized, Size min, Size max)
  4843. {
  4844. Control ctrl = Control.FromHandle (handle);
  4845. SetWindowMinMax (handle, maximized, min, max, ctrl != null ? ctrl.GetCreateParams () : null);
  4846. }
  4847. internal void SetWindowMinMax (IntPtr handle, Rectangle maximized, Size min, Size max, CreateParams cp)
  4848. {
  4849. Hwnd hwnd;
  4850. XSizeHints hints;
  4851. IntPtr dummy;
  4852. hwnd = Hwnd.ObjectFromHandle(handle);
  4853. if (hwnd == null) {
  4854. return;
  4855. }
  4856. min.Width = Math.Max (min.Width, SystemInformation.MinimumWindowSize.Width);
  4857. min.Height = Math.Max (min.Height, SystemInformation.MinimumWindowSize.Height);
  4858. hints = new XSizeHints();
  4859. XGetWMNormalHints(DisplayHandle, hwnd.whole_window, ref hints, out dummy);
  4860. if ((min != Size.Empty) && (min.Width > 0) && (min.Height > 0)) {
  4861. if (cp != null)
  4862. min = TranslateWindowSizeToXWindowSize (cp, min);
  4863. hints.flags = (IntPtr)((int)hints.flags | (int)XSizeHintsFlags.PMinSize);
  4864. hints.min_width = min.Width;
  4865. hints.min_height = min.Height;
  4866. }
  4867. if ((max != Size.Empty) && (max.Width > 0) && (max.Height > 0)) {
  4868. if (cp != null)
  4869. max = TranslateWindowSizeToXWindowSize (cp, max);
  4870. hints.flags = (IntPtr)((int)hints.flags | (int)XSizeHintsFlags.PMaxSize);
  4871. hints.max_width = max.Width;
  4872. hints.max_height = max.Height;
  4873. }
  4874. if (hints.flags != IntPtr.Zero) {
  4875. // The Metacity team has decided that they won't care about this when clicking the maximize icon,
  4876. // they will maximize the window to fill the screen/parent no matter what.
  4877. // http://bugzilla.ximian.com/show_bug.cgi?id=80021
  4878. XSetWMNormalHints(DisplayHandle, hwnd.whole_window, ref hints);
  4879. }
  4880. if ((maximized != Rectangle.Empty) && (maximized.Width > 0) && (maximized.Height > 0)) {
  4881. if (cp != null)
  4882. maximized.Size = TranslateWindowSizeToXWindowSize (cp);
  4883. hints.flags = (IntPtr)XSizeHintsFlags.PPosition;
  4884. hints.x = maximized.X;
  4885. hints.y = maximized.Y;
  4886. hints.width = maximized.Width;
  4887. hints.height = maximized.Height;
  4888. // Metacity does not seem to follow this constraint for maximized (zoomed) windows
  4889. XSetZoomHints(DisplayHandle, hwnd.whole_window, ref hints);
  4890. }
  4891. }
  4892. internal override void SetWindowPos(IntPtr handle, int x, int y, int width, int height)
  4893. {
  4894. Hwnd hwnd;
  4895. hwnd = Hwnd.ObjectFromHandle(handle);
  4896. if (hwnd == null) {
  4897. return;
  4898. }
  4899. // Win32 automatically changes negative width/height to 0.
  4900. if (width < 0)
  4901. width = 0;
  4902. if (height < 0)
  4903. height = 0;
  4904. // X requires a sanity check for width & height; otherwise it dies
  4905. if (hwnd.zero_sized && width > 0 && height > 0) {
  4906. if (hwnd.visible) {
  4907. MapWindow(hwnd, WindowType.Whole);
  4908. }
  4909. hwnd.zero_sized = false;
  4910. }
  4911. if ((width < 1) || (height < 1)) {
  4912. hwnd.zero_sized = true;
  4913. UnmapWindow(hwnd, WindowType.Whole);
  4914. }
  4915. // Save a server roundtrip (and prevent a feedback loop)
  4916. if ((hwnd.x == x) && (hwnd.y == y) &&
  4917. (hwnd.width == width) && (hwnd.height == height)) {
  4918. return;
  4919. }
  4920. if (!hwnd.zero_sized) {
  4921. //Hack?
  4922. hwnd.x = x;
  4923. hwnd.y = y;
  4924. hwnd.width = width;
  4925. hwnd.height = height;
  4926. SendMessage(hwnd.client_window, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
  4927. if (hwnd.fixed_size) {
  4928. SetWindowMinMax(handle, Rectangle.Empty, new Size(width, height), new Size(width, height));
  4929. }
  4930. lock (XlibLock) {
  4931. Control ctrl = Control.FromHandle (handle);
  4932. Size TranslatedSize = TranslateWindowSizeToXWindowSize (ctrl.GetCreateParams (), new Size (width, height));
  4933. MoveResizeWindow (DisplayHandle, hwnd.whole_window, x, y, TranslatedSize.Width, TranslatedSize.Height);
  4934. PerformNCCalc(hwnd);
  4935. }
  4936. }
  4937. // Update our position/size immediately, so
  4938. // that future calls to SetWindowPos aren't
  4939. // kept from calling XMoveResizeWindow (by the
  4940. // "Save a server roundtrip" block above).
  4941. hwnd.x = x;
  4942. hwnd.y = y;
  4943. hwnd.width = width;
  4944. hwnd.height = height;
  4945. hwnd.ClientRect = Rectangle.Empty;
  4946. }
  4947. internal override void SetWindowState(IntPtr handle, FormWindowState state)
  4948. {
  4949. FormWindowState current_state;
  4950. Hwnd hwnd;
  4951. hwnd = Hwnd.ObjectFromHandle(handle);
  4952. current_state = GetWindowState(handle);
  4953. if (current_state == state) {
  4954. return;
  4955. }
  4956. switch(state) {
  4957. case FormWindowState.Normal: {
  4958. lock (XlibLock) {
  4959. if (current_state == FormWindowState.Minimized) {
  4960. MapWindow(hwnd, WindowType.Both);
  4961. } else if (current_state == FormWindowState.Maximized) {
  4962. SendNetWMMessage(hwnd.whole_window, _NET_WM_STATE, (IntPtr)2 /* toggle */, _NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_MAXIMIZED_VERT);
  4963. }
  4964. }
  4965. Activate(handle);
  4966. return;
  4967. }
  4968. case FormWindowState.Minimized: {
  4969. lock (XlibLock) {
  4970. if (current_state == FormWindowState.Maximized) {
  4971. SendNetWMMessage(hwnd.whole_window, _NET_WM_STATE, (IntPtr)2 /* toggle */, _NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_MAXIMIZED_VERT);
  4972. }
  4973. XIconifyWindow(DisplayHandle, hwnd.whole_window, ScreenNo);
  4974. }
  4975. return;
  4976. }
  4977. case FormWindowState.Maximized: {
  4978. lock (XlibLock) {
  4979. if (current_state == FormWindowState.Minimized) {
  4980. MapWindow(hwnd, WindowType.Both);
  4981. }
  4982. SendNetWMMessage(hwnd.whole_window, _NET_WM_STATE, (IntPtr)1 /* Add */, _NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_MAXIMIZED_VERT);
  4983. }
  4984. Activate(handle);
  4985. return;
  4986. }
  4987. }
  4988. }
  4989. internal override void SetWindowStyle(IntPtr handle, CreateParams cp)
  4990. {
  4991. Hwnd hwnd;
  4992. hwnd = Hwnd.ObjectFromHandle(handle);
  4993. SetHwndStyles(hwnd, cp);
  4994. SetWMStyles(hwnd, cp);
  4995. }
  4996. internal override double GetWindowTransparency(IntPtr handle)
  4997. {
  4998. return 1.0;
  4999. }
  5000. internal override void SetWindowTransparency(IntPtr handle, double transparency, Color key)
  5001. {
  5002. Hwnd hwnd;
  5003. IntPtr opacity;
  5004. hwnd = Hwnd.ObjectFromHandle(handle);
  5005. if (hwnd == null) {
  5006. return;
  5007. }
  5008. hwnd.opacity = (uint)(0xffffffff * transparency);
  5009. opacity = (IntPtr)((int)hwnd.opacity);
  5010. IntPtr w = hwnd.whole_window;
  5011. if (hwnd.reparented)
  5012. w = XGetParent (hwnd.whole_window);
  5013. XChangeProperty(DisplayHandle, w, _NET_WM_WINDOW_OPACITY, (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, ref opacity, 1);
  5014. }
  5015. internal override bool SetZOrder(IntPtr handle, IntPtr after_handle, bool top, bool bottom)
  5016. {
  5017. Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
  5018. if (!hwnd.mapped) {
  5019. return false;
  5020. }
  5021. if (top) {
  5022. lock (XlibLock) {
  5023. XRaiseWindow(DisplayHandle, hwnd.whole_window);
  5024. }
  5025. return true;
  5026. } else if (!bottom) {
  5027. Hwnd after_hwnd = null;
  5028. if (after_handle != IntPtr.Zero) {
  5029. after_hwnd = Hwnd.ObjectFromHandle(after_handle);
  5030. }
  5031. XWindowChanges values = new XWindowChanges();
  5032. if (after_hwnd == null) {
  5033. // Work around metacity 'issues'
  5034. int[] atoms;
  5035. atoms = new int[2];
  5036. atoms[0] = unixtime();
  5037. XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_USER_TIME, (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, atoms, 1);
  5038. XRaiseWindow(DisplayHandle, hwnd.whole_window);
  5039. SendNetWMMessage(hwnd.whole_window, _NET_ACTIVE_WINDOW, (IntPtr)1, IntPtr.Zero, IntPtr.Zero);
  5040. return true;
  5041. //throw new ArgumentNullException("after_handle", "Need sibling to adjust z-order");
  5042. }
  5043. values.sibling = after_hwnd.whole_window;
  5044. values.stack_mode = StackMode.Below;
  5045. lock (XlibLock) {
  5046. XConfigureWindow(DisplayHandle, hwnd.whole_window, ChangeWindowFlags.CWStackMode | ChangeWindowFlags.CWSibling, ref values);
  5047. }
  5048. } else {
  5049. // Bottom
  5050. lock (XlibLock) {
  5051. XLowerWindow(DisplayHandle, hwnd.whole_window);
  5052. }
  5053. return true;
  5054. }
  5055. return false;
  5056. }
  5057. internal override void ShowCursor(bool show)
  5058. {
  5059. ; // FIXME - X11 doesn't 'hide' the cursor. we could create an empty cursor
  5060. }
  5061. internal override object StartLoop(Thread thread)
  5062. {
  5063. XEventQueue q = ThreadQueue(thread);
  5064. return q;
  5065. }
  5066. internal override TransparencySupport SupportsTransparency()
  5067. {
  5068. // We need to check if the x compositing manager is running
  5069. return TransparencySupport.Set;
  5070. }
  5071. internal override bool SystrayAdd(IntPtr handle, string tip, Icon icon, out ToolTip tt)
  5072. {
  5073. GetSystrayManagerWindow();
  5074. if (SystrayMgrWindow != IntPtr.Zero) {
  5075. XSizeHints size_hints;
  5076. Hwnd hwnd;
  5077. hwnd = Hwnd.ObjectFromHandle(handle);
  5078. DriverDebug("Adding Systray Whole:{0:X}, Client:{1:X}", hwnd.whole_window.ToInt32(), hwnd.client_window.ToInt32());
  5079. // Oh boy.
  5080. if (hwnd.client_window != hwnd.whole_window) {
  5081. Keyboard.DestroyICForWindow (hwnd.client_window);
  5082. XDestroyWindow(DisplayHandle, hwnd.client_window);
  5083. hwnd.client_window = hwnd.whole_window;
  5084. }
  5085. /* by virtue of the way the tests are ordered when determining if it's PAINT
  5086. or NCPAINT, client_window == whole_window will always be PAINT. So, if we're
  5087. waiting on an nc_expose, drop it and remove the hwnd from the list (unless
  5088. there's a pending expose). */
  5089. if (hwnd.nc_expose_pending) {
  5090. hwnd.nc_expose_pending = false;
  5091. if (!hwnd.expose_pending)
  5092. hwnd.Queue.Paint.Remove (hwnd);
  5093. }
  5094. // We are going to be directly mapped by the system tray, so mark as mapped
  5095. // so we can later properly unmap it.
  5096. hwnd.mapped = true;
  5097. size_hints = new XSizeHints();
  5098. size_hints.flags = (IntPtr)(XSizeHintsFlags.PMinSize | XSizeHintsFlags.PMaxSize | XSizeHintsFlags.PBaseSize);
  5099. size_hints.min_width = 24;
  5100. size_hints.min_height = 24;
  5101. size_hints.max_width = 24;
  5102. size_hints.max_height = 24;
  5103. size_hints.base_width = 24;
  5104. size_hints.base_height = 24;
  5105. XSetWMNormalHints(DisplayHandle, hwnd.whole_window, ref size_hints);
  5106. int[] atoms = new int[2];
  5107. atoms [0] = 1; // Version 1
  5108. atoms [1] = 1; // we want to be mapped
  5109. // This line cost me 3 days...
  5110. XChangeProperty(DisplayHandle, hwnd.whole_window, _XEMBED_INFO, _XEMBED_INFO, 32, PropertyMode.Replace, atoms, 2);
  5111. // Need to pick some reasonable defaults
  5112. tt = new ToolTip();
  5113. tt.AutomaticDelay = 350;
  5114. tt.InitialDelay = 250;
  5115. tt.ReshowDelay = 250;
  5116. tt.ShowAlways = true;
  5117. if ((tip != null) && (tip != string.Empty)) {
  5118. tt.SetToolTip(Control.FromHandle(handle), tip);
  5119. tt.Active = true;
  5120. } else {
  5121. tt.Active = false;
  5122. }
  5123. SendNetClientMessage(SystrayMgrWindow, _NET_SYSTEM_TRAY_OPCODE, IntPtr.Zero, (IntPtr)SystrayRequest.SYSTEM_TRAY_REQUEST_DOCK, hwnd.whole_window);
  5124. return true;
  5125. }
  5126. tt = null;
  5127. return false;
  5128. }
  5129. internal override bool SystrayChange(IntPtr handle, string tip, Icon icon, ref ToolTip tt)
  5130. {
  5131. Control control;
  5132. control = Control.FromHandle(handle);
  5133. if (control != null && tt != null) {
  5134. tt.SetToolTip(control, tip);
  5135. tt.Active = true;
  5136. SendMessage(handle, Msg.WM_PAINT, IntPtr.Zero, IntPtr.Zero);
  5137. return true;
  5138. } else {
  5139. return false;
  5140. }
  5141. }
  5142. internal override void SystrayRemove(IntPtr handle, ref ToolTip tt)
  5143. {
  5144. SetVisible (handle, false, false);
  5145. // The caller can now re-dock it later...
  5146. if (tt != null) {
  5147. tt.Dispose();
  5148. tt = null;
  5149. }
  5150. // Close any balloon window *we* fired.
  5151. ThemeEngine.Current.HideBalloonWindow (handle);
  5152. }
  5153. internal override void SystrayBalloon(IntPtr handle, int timeout, string title, string text, ToolTipIcon icon)
  5154. {
  5155. ThemeEngine.Current.ShowBalloonWindow (handle, timeout, title, text, icon);
  5156. SendMessage(handle, Msg.WM_USER, IntPtr.Zero, (IntPtr) Msg.NIN_BALLOONSHOW);
  5157. }
  5158. internal override bool Text(IntPtr handle, string text)
  5159. {
  5160. Hwnd hwnd;
  5161. hwnd = Hwnd.ObjectFromHandle(handle);
  5162. lock (XlibLock) {
  5163. XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_NAME, UTF8_STRING, 8,
  5164. PropertyMode.Replace, text, Encoding.UTF8.GetByteCount (text));
  5165. // XXX this has problems with UTF8.
  5166. // we need to either use the actual
  5167. // text if it's latin-1, or convert it
  5168. // to compound text if it's in a
  5169. // different charset.
  5170. XStoreName(DisplayHandle, Hwnd.ObjectFromHandle(handle).whole_window, text);
  5171. }
  5172. return true;
  5173. }
  5174. internal override bool TranslateMessage(ref MSG msg)
  5175. {
  5176. return Keyboard.TranslateMessage (ref msg);
  5177. }
  5178. internal override void UpdateWindow(IntPtr handle)
  5179. {
  5180. Hwnd hwnd;
  5181. hwnd = Hwnd.ObjectFromHandle(handle);
  5182. if (!hwnd.visible || !hwnd.expose_pending || !hwnd.Mapped) {
  5183. return;
  5184. }
  5185. SendMessage(handle, Msg.WM_PAINT, IntPtr.Zero, IntPtr.Zero);
  5186. hwnd.Queue.Paint.Remove(hwnd);
  5187. }
  5188. internal override void CreateOffscreenDrawable (IntPtr handle,
  5189. int width, int height,
  5190. out object offscreen_drawable)
  5191. {
  5192. IntPtr root_out;
  5193. int x_out, y_out, width_out, height_out, border_width_out, depth_out;
  5194. XGetGeometry (DisplayHandle, handle,
  5195. out root_out,
  5196. out x_out, out y_out,
  5197. out width_out, out height_out,
  5198. out border_width_out, out depth_out);
  5199. IntPtr pixmap = XCreatePixmap (DisplayHandle, handle, width, height, depth_out);
  5200. offscreen_drawable = pixmap;
  5201. }
  5202. internal override void DestroyOffscreenDrawable (object offscreen_drawable)
  5203. {
  5204. XFreePixmap (DisplayHandle, (IntPtr)offscreen_drawable);
  5205. }
  5206. internal override Graphics GetOffscreenGraphics (object offscreen_drawable)
  5207. {
  5208. return Graphics.FromHwnd ((IntPtr) offscreen_drawable);
  5209. }
  5210. internal override void BlitFromOffscreen (IntPtr dest_handle,
  5211. Graphics dest_dc,
  5212. object offscreen_drawable,
  5213. Graphics offscreen_dc,
  5214. Rectangle r)
  5215. {
  5216. XGCValues gc_values;
  5217. IntPtr gc;
  5218. gc_values = new XGCValues();
  5219. gc = XCreateGC (DisplayHandle, dest_handle, IntPtr.Zero, ref gc_values);
  5220. XCopyArea (DisplayHandle, (IntPtr)offscreen_drawable, dest_handle,
  5221. gc, r.X, r.Y, r.Width, r.Height, r.X, r.Y);
  5222. XFreeGC (DisplayHandle, gc);
  5223. }
  5224. #endregion // Public Static Methods
  5225. #region Events
  5226. internal override event EventHandler Idle;
  5227. #endregion // Events
  5228. #if TRACE
  5229. #region Xcursor imports
  5230. [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadCursor")]
  5231. internal extern static IntPtr XcursorLibraryLoadCursor (IntPtr display, [MarshalAs (UnmanagedType.LPStr)] string name);
  5232. [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadImages")]
  5233. internal extern static IntPtr XcursorLibraryLoadImages ([MarshalAs (UnmanagedType.LPStr)] string file, IntPtr theme, int size);
  5234. [DllImport ("libXcursor", EntryPoint = "XcursorImagesDestroy")]
  5235. internal extern static void XcursorImagesDestroy (IntPtr images);
  5236. [DllImport ("libXcursor", EntryPoint = "XcursorGetDefaultSize")]
  5237. internal extern static int XcursorGetDefaultSize (IntPtr display);
  5238. [DllImport ("libXcursor", EntryPoint = "XcursorImageLoadCursor")]
  5239. internal extern static IntPtr XcursorImageLoadCursor (IntPtr display, IntPtr image);
  5240. [DllImport ("libXcursor", EntryPoint = "XcursorGetTheme")]
  5241. internal extern static IntPtr XcursorGetTheme (IntPtr display);
  5242. #endregion
  5243. #region X11 Imports
  5244. [DllImport ("libX11", EntryPoint="XOpenDisplay")]
  5245. internal extern static IntPtr XOpenDisplay(IntPtr display);
  5246. [DllImport ("libX11", EntryPoint="XCloseDisplay")]
  5247. internal extern static int XCloseDisplay(IntPtr display);
  5248. [DllImport ("libX11", EntryPoint="XSynchronize")]
  5249. internal extern static IntPtr XSynchronize(IntPtr display, bool onoff);
  5250. [DllImport ("libX11", EntryPoint="XCreateWindow")]
  5251. 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, UIntPtr valuemask, ref XSetWindowAttributes attributes);
  5252. internal static IntPtr XCreateWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, int depth, int xclass, IntPtr visual, UIntPtr valuemask, ref XSetWindowAttributes attributes)
  5253. {
  5254. DebugHelper.TraceWriteLine ("XCreateWindow");
  5255. return _XCreateWindow(display, parent, x, y, width, height,
  5256. border_width, depth, xclass, visual, valuemask, ref attributes);
  5257. }
  5258. [DllImport ("libX11", EntryPoint="XCreateSimpleWindow")]
  5259. internal extern static IntPtr _XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, UIntPtr border, UIntPtr background);
  5260. internal static IntPtr XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, UIntPtr border, UIntPtr background)
  5261. {
  5262. DebugHelper.TraceWriteLine ("XCreateSimpleWindow");
  5263. return _XCreateSimpleWindow(display, parent, x, y, width, height, border_width, border, background);
  5264. }
  5265. [DllImport ("libX11", EntryPoint="XMapWindow")]
  5266. internal extern static int _XMapWindow(IntPtr display, IntPtr window);
  5267. internal static int XMapWindow(IntPtr display, IntPtr window)
  5268. {
  5269. DebugHelper.TraceWriteLine ("XMapWindow");
  5270. return _XMapWindow(display, window);
  5271. }
  5272. [DllImport ("libX11", EntryPoint="XUnmapWindow")]
  5273. internal extern static int _XUnmapWindow(IntPtr display, IntPtr window);
  5274. internal static int XUnmapWindow(IntPtr display, IntPtr window)
  5275. {
  5276. DebugHelper.TraceWriteLine ("XUnmapWindow");
  5277. return _XUnmapWindow(display, window);
  5278. }
  5279. [DllImport ("libX11", EntryPoint="XMapSubwindows")]
  5280. internal extern static int _XMapSubindows(IntPtr display, IntPtr window);
  5281. internal static int XMapSubindows(IntPtr display, IntPtr window)
  5282. {
  5283. DebugHelper.TraceWriteLine ("XMapSubindows");
  5284. return _XMapSubindows(display, window);
  5285. }
  5286. [DllImport ("libX11", EntryPoint="XUnmapSubwindows")]
  5287. internal extern static int _XUnmapSubwindows(IntPtr display, IntPtr window);
  5288. internal static int XUnmapSubwindows(IntPtr display, IntPtr window)
  5289. {
  5290. DebugHelper.TraceWriteLine ("XUnmapSubwindows");
  5291. return _XUnmapSubwindows(display, window);
  5292. }
  5293. [DllImport ("libX11", EntryPoint="XRootWindow")]
  5294. internal extern static IntPtr _XRootWindow(IntPtr display, int screen_number);
  5295. internal static IntPtr XRootWindow(IntPtr display, int screen_number)
  5296. {
  5297. DebugHelper.TraceWriteLine ("XRootWindow");
  5298. return _XRootWindow(display, screen_number);
  5299. }
  5300. [DllImport ("libX11", EntryPoint="XNextEvent")]
  5301. internal extern static IntPtr _XNextEvent(IntPtr display, ref XEvent xevent);
  5302. internal static IntPtr XNextEvent(IntPtr display, ref XEvent xevent)
  5303. {
  5304. DebugHelper.TraceWriteLine ("XNextEvent");
  5305. return _XNextEvent(display, ref xevent);
  5306. }
  5307. [DllImport ("libX11", EntryPoint="XConnectionNumber")]
  5308. internal extern static int _XConnectionNumber (IntPtr display);
  5309. internal static int XConnectionNumber (IntPtr display)
  5310. {
  5311. DebugHelper.TraceWriteLine ("XConnectionNumber");
  5312. return _XConnectionNumber (display);
  5313. }
  5314. [DllImport ("libX11", EntryPoint="XPending")]
  5315. internal extern static int _XPending (IntPtr display);
  5316. internal static int XPending (IntPtr display)
  5317. {
  5318. DebugHelper.TraceWriteLine ("XPending");
  5319. DebugHelper.DumpCallers (3);
  5320. return _XPending (display);
  5321. }
  5322. [DllImport ("libX11", EntryPoint="XSelectInput")]
  5323. internal extern static IntPtr _XSelectInput(IntPtr display, IntPtr window, IntPtr mask);
  5324. internal static IntPtr XSelectInput(IntPtr display, IntPtr window, IntPtr mask)
  5325. {
  5326. DebugHelper.TraceWriteLine ("XSelectInput");
  5327. return _XSelectInput(display, window, mask);
  5328. }
  5329. [DllImport ("libX11", EntryPoint="XDestroyWindow")]
  5330. internal extern static int _XDestroyWindow(IntPtr display, IntPtr window);
  5331. internal static int XDestroyWindow(IntPtr display, IntPtr window)
  5332. {
  5333. DebugHelper.TraceWriteLine ("XDestroyWindow 0x{0:x}", window.ToInt32());
  5334. return _XDestroyWindow(display, window);
  5335. }
  5336. [DllImport ("libX11", EntryPoint="XReparentWindow")]
  5337. internal extern static int _XReparentWindow(IntPtr display, IntPtr window, IntPtr parent, int x, int y);
  5338. internal static int XReparentWindow(IntPtr display, IntPtr window, IntPtr parent, int x, int y)
  5339. {
  5340. DebugHelper.TraceWriteLine ("XReparentWindow");
  5341. return _XReparentWindow(display, window, parent, x, y);
  5342. }
  5343. [DllImport ("libX11", EntryPoint="XMoveResizeWindow")]
  5344. extern static int _XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height);
  5345. static int XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height) {
  5346. DebugHelper.TraceWriteLine ("XMoveResizeWindow");
  5347. return _XMoveResizeWindow(display, window, x, y, width, height);
  5348. }
  5349. internal static int MoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height)
  5350. {
  5351. int ret = XMoveResizeWindow (display, window, x, y, width, height);
  5352. Keyboard.MoveCurrentCaretPos ();
  5353. return ret;
  5354. }
  5355. [DllImport ("libX11", EntryPoint="XResizeWindow")]
  5356. internal extern static int _XResizeWindow(IntPtr display, IntPtr window, int width, int height);
  5357. internal static int XResizeWindow(IntPtr display, IntPtr window, int width, int height)
  5358. {
  5359. DebugHelper.TraceWriteLine ("XResizeWindow");
  5360. return _XResizeWindow(display, window, width, height);
  5361. }
  5362. [DllImport ("libX11", EntryPoint="XGetWindowAttributes")]
  5363. internal extern static int _XGetWindowAttributes(IntPtr display, IntPtr window, ref XWindowAttributes attributes);
  5364. internal static int XGetWindowAttributes(IntPtr display, IntPtr window, ref XWindowAttributes attributes)
  5365. {
  5366. DebugHelper.TraceWriteLine ("XGetWindowAttributes");
  5367. return _XGetWindowAttributes(display, window, ref attributes);
  5368. }
  5369. [DllImport ("libX11", EntryPoint="XFlush")]
  5370. internal extern static int _XFlush(IntPtr display);
  5371. internal static int XFlush(IntPtr display)
  5372. {
  5373. DebugHelper.TraceWriteLine ("XFlush");
  5374. return _XFlush(display);
  5375. }
  5376. [DllImport ("libX11", EntryPoint="XSetWMName")]
  5377. internal extern static int _XSetWMName(IntPtr display, IntPtr window, ref XTextProperty text_prop);
  5378. internal static int XSetWMName(IntPtr display, IntPtr window, ref XTextProperty text_prop)
  5379. {
  5380. DebugHelper.TraceWriteLine ("XSetWMName");
  5381. return _XSetWMName(display, window, ref text_prop);
  5382. }
  5383. [DllImport ("libX11", EntryPoint="XStoreName")]
  5384. internal extern static int _XStoreName(IntPtr display, IntPtr window, string window_name);
  5385. internal static int XStoreName(IntPtr display, IntPtr window, string window_name)
  5386. {
  5387. DebugHelper.TraceWriteLine ("XStoreName");
  5388. return _XStoreName(display, window, window_name);
  5389. }
  5390. [DllImport ("libX11", EntryPoint="XFetchName")]
  5391. internal extern static int _XFetchName(IntPtr display, IntPtr window, ref IntPtr window_name);
  5392. internal static int XFetchName(IntPtr display, IntPtr window, ref IntPtr window_name)
  5393. {
  5394. DebugHelper.TraceWriteLine ("XFetchName");
  5395. return _XFetchName(display, window, ref window_name);
  5396. }
  5397. [DllImport ("libX11", EntryPoint="XSendEvent")]
  5398. internal extern static int _XSendEvent(IntPtr display, IntPtr window, bool propagate, IntPtr event_mask, ref XEvent send_event);
  5399. internal static int XSendEvent(IntPtr display, IntPtr window, bool propagate, IntPtr event_mask, ref XEvent send_event)
  5400. {
  5401. DebugHelper.TraceWriteLine ("XSendEvent");
  5402. return _XSendEvent(display, window, propagate, event_mask, ref send_event);
  5403. }
  5404. [DllImport ("libX11", EntryPoint="XQueryTree")]
  5405. 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);
  5406. internal static int XQueryTree(IntPtr display, IntPtr window, out IntPtr root_return, out IntPtr parent_return, out IntPtr children_return, out int nchildren_return)
  5407. {
  5408. DebugHelper.TraceWriteLine ("XQueryTree");
  5409. return _XQueryTree(display, window, out root_return, out parent_return, out children_return, out nchildren_return);
  5410. }
  5411. [DllImport ("libX11", EntryPoint="XFree")]
  5412. internal extern static int _XFree(IntPtr data);
  5413. internal static int XFree(IntPtr data)
  5414. {
  5415. DebugHelper.TraceWriteLine ("XFree");
  5416. return _XFree(data);
  5417. }
  5418. [DllImport ("libX11", EntryPoint="XRaiseWindow")]
  5419. internal extern static int _XRaiseWindow(IntPtr display, IntPtr window);
  5420. internal static int XRaiseWindow(IntPtr display, IntPtr window)
  5421. {
  5422. DebugHelper.TraceWriteLine ("XRaiseWindow");
  5423. return _XRaiseWindow(display, window);
  5424. }
  5425. [DllImport ("libX11", EntryPoint="XLowerWindow")]
  5426. internal extern static uint _XLowerWindow(IntPtr display, IntPtr window);
  5427. internal static uint XLowerWindow(IntPtr display, IntPtr window)
  5428. {
  5429. DebugHelper.TraceWriteLine ("XLowerWindow");
  5430. return _XLowerWindow(display, window);
  5431. }
  5432. [DllImport ("libX11", EntryPoint="XConfigureWindow")]
  5433. internal extern static uint _XConfigureWindow(IntPtr display, IntPtr window, ChangeWindowFlags value_mask, ref XWindowChanges values);
  5434. internal static uint XConfigureWindow(IntPtr display, IntPtr window, ChangeWindowFlags value_mask, ref XWindowChanges values)
  5435. {
  5436. DebugHelper.TraceWriteLine ("XConfigureWindow");
  5437. return _XConfigureWindow(display, window, value_mask, ref values);
  5438. }
  5439. [DllImport ("libX11", EntryPoint="XInternAtom")]
  5440. internal extern static IntPtr _XInternAtom(IntPtr display, string atom_name, bool only_if_exists);
  5441. internal static IntPtr XInternAtom(IntPtr display, string atom_name, bool only_if_exists)
  5442. {
  5443. DebugHelper.TraceWriteLine ("XInternAtom");
  5444. return _XInternAtom(display, atom_name, only_if_exists);
  5445. }
  5446. [DllImport ("libX11", EntryPoint="XInternAtoms")]
  5447. internal extern static int _XInternAtoms(IntPtr display, string[] atom_names, int atom_count, bool only_if_exists, IntPtr[] atoms);
  5448. internal static int XInternAtoms(IntPtr display, string[] atom_names, int atom_count, bool only_if_exists, IntPtr[] atoms)
  5449. {
  5450. DebugHelper.TraceWriteLine ("XInternAtoms");
  5451. return _XInternAtoms(display, atom_names, atom_count, only_if_exists, atoms);
  5452. }
  5453. [DllImport ("libX11", EntryPoint="XSetWMProtocols")]
  5454. internal extern static int _XSetWMProtocols(IntPtr display, IntPtr window, IntPtr[] protocols, int count);
  5455. internal static int XSetWMProtocols(IntPtr display, IntPtr window, IntPtr[] protocols, int count)
  5456. {
  5457. DebugHelper.TraceWriteLine ("XSetWMProtocols");
  5458. return _XSetWMProtocols(display, window, protocols, count);
  5459. }
  5460. [DllImport ("libX11", EntryPoint="XGrabPointer")]
  5461. internal extern static int _XGrabPointer(IntPtr display, IntPtr window, bool owner_events, EventMask event_mask, GrabMode pointer_mode, GrabMode keyboard_mode, IntPtr confine_to, IntPtr cursor, IntPtr timestamp);
  5462. internal static int XGrabPointer(IntPtr display, IntPtr window, bool owner_events, EventMask event_mask, GrabMode pointer_mode, GrabMode keyboard_mode, IntPtr confine_to, IntPtr cursor, IntPtr timestamp)
  5463. {
  5464. DebugHelper.TraceWriteLine ("XGrabPointer");
  5465. return _XGrabPointer(display, window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor, timestamp);
  5466. }
  5467. [DllImport ("libX11", EntryPoint="XUngrabPointer")]
  5468. internal extern static int _XUngrabPointer(IntPtr display, IntPtr timestamp);
  5469. internal static int XUngrabPointer(IntPtr display, IntPtr timestamp)
  5470. {
  5471. DebugHelper.TraceWriteLine ("XUngrabPointer");
  5472. return _XUngrabPointer(display, timestamp);
  5473. }
  5474. [DllImport ("libX11", EntryPoint="XQueryPointer")]
  5475. 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);
  5476. internal 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)
  5477. {
  5478. DebugHelper.TraceWriteLine ("XQueryPointer");
  5479. return _XQueryPointer(display, window, out root, out child, out root_x, out root_y, out win_x, out win_y, out keys_buttons);
  5480. }
  5481. [DllImport ("libX11", EntryPoint="XTranslateCoordinates")]
  5482. 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);
  5483. internal 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)
  5484. {
  5485. DebugHelper.TraceWriteLine ("XTranslateCoordinates");
  5486. return _XTranslateCoordinates (display, src_w, dest_w, src_x, src_y, out intdest_x_return, out dest_y_return, out child_return);
  5487. }
  5488. [DllImport ("libX11", EntryPoint="XGetGeometry")]
  5489. internal extern static bool _XGetGeometry(IntPtr display, IntPtr window, out IntPtr root, out int x, out int y, out int width, out int height, out int border_width, out int depth);
  5490. internal static bool XGetGeometry(IntPtr display, IntPtr window, out IntPtr root, out int x, out int y, out int width, out int height, out int border_width, out int depth)
  5491. {
  5492. DebugHelper.TraceWriteLine ("XGetGeometry");
  5493. return _XGetGeometry(display, window, out root, out x, out y, out width, out height, out border_width, out depth);
  5494. }
  5495. [DllImport ("libX11", EntryPoint="XGetGeometry")]
  5496. internal extern static bool _XGetGeometry(IntPtr display, IntPtr window, IntPtr root, out int x, out int y, out int width, out int height, IntPtr border_width, IntPtr depth);
  5497. internal static bool XGetGeometry(IntPtr display, IntPtr window, IntPtr root, out int x, out int y, out int width, out int height, IntPtr border_width, IntPtr depth)
  5498. {
  5499. DebugHelper.TraceWriteLine ("XGetGeometry");
  5500. return _XGetGeometry(display, window, root, out x, out y, out width, out height, border_width, depth);
  5501. }
  5502. [DllImport ("libX11", EntryPoint="XGetGeometry")]
  5503. internal extern static bool _XGetGeometry(IntPtr display, IntPtr window, IntPtr root, out int x, out int y, IntPtr width, IntPtr height, IntPtr border_width, IntPtr depth);
  5504. internal static bool XGetGeometry(IntPtr display, IntPtr window, IntPtr root, out int x, out int y, IntPtr width, IntPtr height, IntPtr border_width, IntPtr depth)
  5505. {
  5506. DebugHelper.TraceWriteLine ("XGetGeometry");
  5507. return _XGetGeometry(display, window, root, out x, out y, width, height, border_width, depth);
  5508. }
  5509. [DllImport ("libX11", EntryPoint="XGetGeometry")]
  5510. internal extern static bool _XGetGeometry(IntPtr display, IntPtr window, IntPtr root, IntPtr x, IntPtr y, out int width, out int height, IntPtr border_width, IntPtr depth);
  5511. internal static bool XGetGeometry(IntPtr display, IntPtr window, IntPtr root, IntPtr x, IntPtr y, out int width, out int height, IntPtr border_width, IntPtr depth)
  5512. {
  5513. DebugHelper.TraceWriteLine ("XGetGeometry");
  5514. return _XGetGeometry(display, window, root, x, y, out width, out height, border_width, depth);
  5515. }
  5516. [DllImport ("libX11", EntryPoint="XWarpPointer")]
  5517. 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);
  5518. internal 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)
  5519. {
  5520. DebugHelper.TraceWriteLine ("XWarpPointer");
  5521. return _XWarpPointer(display, src_w, dest_w, src_x, src_y, src_width, src_height, dest_x, dest_y);
  5522. }
  5523. [DllImport ("libX11", EntryPoint="XClearWindow")]
  5524. internal extern static int _XClearWindow(IntPtr display, IntPtr window);
  5525. internal static int XClearWindow(IntPtr display, IntPtr window)
  5526. {
  5527. DebugHelper.TraceWriteLine ("XClearWindow");
  5528. return _XClearWindow(display, window);
  5529. }
  5530. [DllImport ("libX11", EntryPoint="XClearArea")]
  5531. internal extern static int _XClearArea(IntPtr display, IntPtr window, int x, int y, int width, int height, bool exposures);
  5532. internal static int XClearArea(IntPtr display, IntPtr window, int x, int y, int width, int height, bool exposures)
  5533. {
  5534. DebugHelper.TraceWriteLine ("XClearArea");
  5535. return _XClearArea(display, window, x, y, width, height, exposures);
  5536. }
  5537. // Colormaps
  5538. [DllImport ("libX11", EntryPoint="XDefaultScreenOfDisplay")]
  5539. internal extern static IntPtr _XDefaultScreenOfDisplay(IntPtr display);
  5540. internal static IntPtr XDefaultScreenOfDisplay(IntPtr display)
  5541. {
  5542. DebugHelper.TraceWriteLine ("XDefaultScreenOfDisplay");
  5543. return _XDefaultScreenOfDisplay(display);
  5544. }
  5545. [DllImport ("libX11", EntryPoint="XScreenNumberOfScreen")]
  5546. internal extern static int _XScreenNumberOfScreen(IntPtr display, IntPtr Screen);
  5547. internal static int XDefaultScreenOfDisplay(IntPtr display, IntPtr Screen)
  5548. {
  5549. DebugHelper.TraceWriteLine ("XDefaultScreenOfDisplay");
  5550. return _XScreenNumberOfScreen(display, Screen);
  5551. }
  5552. [DllImport ("libX11", EntryPoint="XDefaultVisual")]
  5553. internal extern static IntPtr _XDefaultVisual(IntPtr display, int screen_number);
  5554. internal static IntPtr XDefaultScreenOfDisplay(IntPtr display, int screen_number)
  5555. {
  5556. DebugHelper.TraceWriteLine ("XDefaultScreenOfDisplay");
  5557. return _XDefaultVisual(display, screen_number);
  5558. }
  5559. [DllImport ("libX11", EntryPoint="XDefaultDepth")]
  5560. internal extern static uint _XDefaultDepth(IntPtr display, int screen_number);
  5561. internal static uint XDefaultDepth(IntPtr display, int screen_number)
  5562. {
  5563. DebugHelper.TraceWriteLine ("XDefaultDepth");
  5564. return _XDefaultDepth(display, screen_number);
  5565. }
  5566. [DllImport ("libX11", EntryPoint="XDefaultScreen")]
  5567. internal extern static int _XDefaultScreen(IntPtr display);
  5568. internal static int XDefaultScreen(IntPtr display)
  5569. {
  5570. DebugHelper.TraceWriteLine ("XDefaultScreen");
  5571. return _XDefaultScreen(display);
  5572. }
  5573. [DllImport ("libX11", EntryPoint="XDefaultColormap")]
  5574. internal extern static IntPtr _XDefaultColormap(IntPtr display, int screen_number);
  5575. internal static IntPtr XDefaultColormap(IntPtr display, int screen_number)
  5576. {
  5577. DebugHelper.TraceWriteLine ("XDefaultColormap");
  5578. return _XDefaultColormap(display, screen_number);
  5579. }
  5580. [DllImport ("libX11", EntryPoint="XLookupColor")]
  5581. internal extern static int _XLookupColor(IntPtr display, IntPtr Colormap, string Coloranem, ref XColor exact_def_color, ref XColor screen_def_color);
  5582. internal static int XLookupColor(IntPtr display, IntPtr Colormap, string Coloranem, ref XColor exact_def_color, ref XColor screen_def_color)
  5583. {
  5584. DebugHelper.TraceWriteLine ("XLookupColor");
  5585. return _XLookupColor(display, Colormap, Coloranem, ref exact_def_color, ref screen_def_color);
  5586. }
  5587. [DllImport ("libX11", EntryPoint="XAllocColor")]
  5588. internal extern static int _XAllocColor(IntPtr display, IntPtr Colormap, ref XColor colorcell_def);
  5589. internal static int XAllocColor(IntPtr display, IntPtr Colormap, ref XColor colorcell_def)
  5590. {
  5591. DebugHelper.TraceWriteLine ("XAllocColor");
  5592. return _XAllocColor(display, Colormap, ref colorcell_def);
  5593. }
  5594. [DllImport ("libX11", EntryPoint="XSetTransientForHint")]
  5595. internal extern static int _XSetTransientForHint(IntPtr display, IntPtr window, IntPtr prop_window);
  5596. internal static int XSetTransientForHint(IntPtr display, IntPtr window, IntPtr prop_window)
  5597. {
  5598. DebugHelper.TraceWriteLine ("XSetTransientForHint");
  5599. return _XSetTransientForHint(display, window, prop_window);
  5600. }
  5601. [DllImport ("libX11", EntryPoint="XChangeProperty")]
  5602. internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref MotifWmHints data, int nelements);
  5603. internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref MotifWmHints data, int nelements)
  5604. {
  5605. DebugHelper.TraceWriteLine ("XChangeProperty");
  5606. return _XChangeProperty(display, window, property, type, format, mode, ref data, nelements);
  5607. }
  5608. [DllImport ("libX11", EntryPoint="XChangeProperty")]
  5609. internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref uint value, int nelements);
  5610. internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref uint value, int nelements)
  5611. {
  5612. DebugHelper.TraceWriteLine ("XChangeProperty");
  5613. return _XChangeProperty(display, window, property, type, format, mode, ref value, nelements);
  5614. }
  5615. [DllImport ("libX11", EntryPoint="XChangeProperty")]
  5616. internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref IntPtr value, int nelements);
  5617. internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref IntPtr value, int nelements)
  5618. {
  5619. DebugHelper.TraceWriteLine ("XChangeProperty");
  5620. return _XChangeProperty(display, window, property, type, format, mode, ref value, nelements);
  5621. }
  5622. [DllImport ("libX11", EntryPoint="XChangeProperty")]
  5623. internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, uint[] data, int nelements);
  5624. internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, uint[] data, int nelements)
  5625. {
  5626. DebugHelper.TraceWriteLine ("XChangeProperty");
  5627. return _XChangeProperty(display, window, property, type, format, mode, data, nelements);
  5628. }
  5629. [DllImport ("libX11", EntryPoint="XChangeProperty")]
  5630. internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, int[] data, int nelements);
  5631. internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, int[] data, int nelements)
  5632. {
  5633. DebugHelper.TraceWriteLine ("XChangeProperty");
  5634. return _XChangeProperty(display, window, property, type, format, mode, data, nelements);
  5635. }
  5636. [DllImport ("libX11", EntryPoint="XChangeProperty")]
  5637. internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr[] data, int nelements);
  5638. internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr[] data, int nelements)
  5639. {
  5640. DebugHelper.TraceWriteLine ("XChangeProperty");
  5641. return _XChangeProperty(display, window, property, type, format, mode, data, nelements);
  5642. }
  5643. [DllImport ("libX11", EntryPoint="XChangeProperty")]
  5644. internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr atoms, int nelements);
  5645. internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr atoms, int nelements)
  5646. {
  5647. DebugHelper.TraceWriteLine ("XChangeProperty");
  5648. return _XChangeProperty(display, window, property, type, format, mode, atoms, nelements);
  5649. }
  5650. [DllImport ("libX11", EntryPoint="XChangeProperty", CharSet=CharSet.Ansi)]
  5651. internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, string text, int text_length);
  5652. internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, string text, int text_length)
  5653. {
  5654. DebugHelper.TraceWriteLine ("XChangeProperty");
  5655. return _XChangeProperty(display, window, property, type, format, mode, text, text_length);
  5656. }
  5657. [DllImport ("libX11", EntryPoint="XDeleteProperty")]
  5658. internal extern static int _XDeleteProperty(IntPtr display, IntPtr window, IntPtr property);
  5659. internal static int XDeleteProperty(IntPtr display, IntPtr window, IntPtr property)
  5660. {
  5661. DebugHelper.TraceWriteLine ("XDeleteProperty");
  5662. return _XDeleteProperty(display, window, property);
  5663. }
  5664. // Drawing
  5665. [DllImport ("libX11", EntryPoint="XCreateGC")]
  5666. internal extern static IntPtr _XCreateGC(IntPtr display, IntPtr window, IntPtr valuemask, ref XGCValues values);
  5667. internal static IntPtr XCreateGC(IntPtr display, IntPtr window, IntPtr valuemask, ref XGCValues values)
  5668. {
  5669. DebugHelper.TraceWriteLine ("XCreateGC");
  5670. return _XCreateGC(display, window, valuemask, ref values);
  5671. }
  5672. [DllImport ("libX11", EntryPoint="XFreeGC")]
  5673. internal extern static int _XFreeGC(IntPtr display, IntPtr gc);
  5674. internal static int XFreeGC(IntPtr display, IntPtr gc)
  5675. {
  5676. DebugHelper.TraceWriteLine ("XFreeGC");
  5677. return _XFreeGC(display, gc);
  5678. }
  5679. [DllImport ("libX11", EntryPoint="XSetFunction")]
  5680. internal extern static int _XSetFunction(IntPtr display, IntPtr gc, GXFunction function);
  5681. internal static int XSetFunction(IntPtr display, IntPtr gc, GXFunction function)
  5682. {
  5683. DebugHelper.TraceWriteLine ("XSetFunction");
  5684. return _XSetFunction(display, gc, function);
  5685. }
  5686. [DllImport ("libX11", EntryPoint="XSetLineAttributes")]
  5687. internal extern static int _XSetLineAttributes(IntPtr display, IntPtr gc, int line_width, GCLineStyle line_style, GCCapStyle cap_style, GCJoinStyle join_style);
  5688. internal static int XSetLineAttributes(IntPtr display, IntPtr gc, int line_width, GCLineStyle line_style, GCCapStyle cap_style, GCJoinStyle join_style)
  5689. {
  5690. DebugHelper.TraceWriteLine ("XSetLineAttributes");
  5691. return _XSetLineAttributes(display, gc, line_width, line_style, cap_style, join_style);
  5692. }
  5693. [DllImport ("libX11", EntryPoint="XDrawLine")]
  5694. internal extern static int _XDrawLine(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2);
  5695. internal static int XDrawLine(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2)
  5696. {
  5697. DebugHelper.TraceWriteLine ("XDrawLine");
  5698. return _XDrawLine(display, drawable, gc, x1, y1, x2, y2);
  5699. }
  5700. [DllImport ("libX11", EntryPoint="XDrawRectangle")]
  5701. internal extern static int _XDrawRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
  5702. internal static int XDrawRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height)
  5703. {
  5704. DebugHelper.TraceWriteLine ("XDrawRectangle");
  5705. return _XDrawRectangle(display, drawable, gc, x1, y1, width, height);
  5706. }
  5707. [DllImport ("libX11", EntryPoint="XFillRectangle")]
  5708. internal extern static int _XFillRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
  5709. internal static int XFillRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height)
  5710. {
  5711. DebugHelper.TraceWriteLine ("XFillRectangle");
  5712. return _XFillRectangle(display, drawable, gc, x1, y1, width, height);
  5713. }
  5714. [DllImport ("libX11", EntryPoint="XSetWindowBackground")]
  5715. internal extern static int _XSetWindowBackground(IntPtr display, IntPtr window, IntPtr background);
  5716. internal static int XSetWindowBackground(IntPtr display, IntPtr window, IntPtr background)
  5717. {
  5718. DebugHelper.TraceWriteLine ("XSetWindowBackground");
  5719. return _XSetWindowBackground(display, window, background);
  5720. }
  5721. [DllImport ("libX11", EntryPoint="XCopyArea")]
  5722. 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);
  5723. internal 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)
  5724. {
  5725. DebugHelper.TraceWriteLine ("XCopyArea");
  5726. return _XCopyArea(display, src, dest, gc, src_x, src_y, width, height, dest_x, dest_y);
  5727. }
  5728. [DllImport ("libX11", EntryPoint="XGetWindowProperty")]
  5729. internal extern static int _XGetWindowProperty(IntPtr display, IntPtr window, IntPtr atom, IntPtr long_offset, IntPtr long_length, bool delete, IntPtr req_type, out IntPtr actual_type, out int actual_format, out IntPtr nitems, out IntPtr bytes_after, ref IntPtr prop);
  5730. internal static int XGetWindowProperty(IntPtr display, IntPtr window, IntPtr atom, IntPtr long_offset, IntPtr long_length, bool delete, IntPtr req_type, out IntPtr actual_type, out int actual_format, out IntPtr nitems, out IntPtr bytes_after, ref IntPtr prop)
  5731. {
  5732. DebugHelper.TraceWriteLine ("XGetWindowProperty");
  5733. return _XGetWindowProperty(display, window, atom, long_offset, long_length, delete, req_type, out actual_type, out actual_format, out nitems, out bytes_after, ref prop);
  5734. }
  5735. [DllImport ("libX11", EntryPoint="XSetInputFocus")]
  5736. internal extern static int _XSetInputFocus(IntPtr display, IntPtr window, RevertTo revert_to, IntPtr time);
  5737. internal static int XSetInputFocus(IntPtr display, IntPtr window, RevertTo revert_to, IntPtr time)
  5738. {
  5739. DebugHelper.TraceWriteLine ("XSetInputFocus");
  5740. return _XSetInputFocus(display, window, revert_to, time);
  5741. }
  5742. [DllImport ("libX11", EntryPoint="XIconifyWindow")]
  5743. internal extern static int _XIconifyWindow(IntPtr display, IntPtr window, int screen_number);
  5744. internal static int XIconifyWindow(IntPtr display, IntPtr window, int screen_number)
  5745. {
  5746. DebugHelper.TraceWriteLine ("XIconifyWindow");
  5747. return _XIconifyWindow(display, window, screen_number);
  5748. }
  5749. [DllImport ("libX11", EntryPoint="XDefineCursor")]
  5750. internal extern static int _XDefineCursor(IntPtr display, IntPtr window, IntPtr cursor);
  5751. internal static int XDefineCursor(IntPtr display, IntPtr window, IntPtr cursor)
  5752. {
  5753. DebugHelper.TraceWriteLine ("XDefineCursor");
  5754. return _XDefineCursor(display, window, cursor);
  5755. }
  5756. [DllImport ("libX11", EntryPoint="XUndefineCursor")]
  5757. internal extern static int _XUndefineCursor(IntPtr display, IntPtr window);
  5758. internal static int XUndefineCursor(IntPtr display, IntPtr window)
  5759. {
  5760. DebugHelper.TraceWriteLine ("XUndefineCursor");
  5761. return _XUndefineCursor(display, window);
  5762. }
  5763. [DllImport ("libX11", EntryPoint="XFreeCursor")]
  5764. internal extern static int _XFreeCursor(IntPtr display, IntPtr cursor);
  5765. internal static int XFreeCursor(IntPtr display, IntPtr cursor)
  5766. {
  5767. DebugHelper.TraceWriteLine ("XFreeCursor");
  5768. return _XFreeCursor(display, cursor);
  5769. }
  5770. [DllImport ("libX11", EntryPoint="XCreateFontCursor")]
  5771. internal extern static IntPtr _XCreateFontCursor(IntPtr display, CursorFontShape shape);
  5772. internal static IntPtr XCreateFontCursor(IntPtr display, CursorFontShape shape)
  5773. {
  5774. DebugHelper.TraceWriteLine ("XCreateFontCursor");
  5775. return _XCreateFontCursor(display, shape);
  5776. }
  5777. [DllImport ("libX11", EntryPoint="XCreatePixmapCursor")]
  5778. 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);
  5779. internal static IntPtr XCreatePixmapCursor(IntPtr display, IntPtr source, IntPtr mask, ref XColor foreground_color, ref XColor background_color, int x_hot, int y_hot)
  5780. {
  5781. DebugHelper.TraceWriteLine ("XCreatePixmapCursor");
  5782. return _XCreatePixmapCursor(display, source, mask, ref foreground_color, ref background_color, x_hot, y_hot);
  5783. }
  5784. [DllImport ("libX11", EntryPoint="XCreatePixmapFromBitmapData")]
  5785. internal extern static IntPtr _XCreatePixmapFromBitmapData(IntPtr display, IntPtr drawable, byte[] data, int width, int height, IntPtr fg, IntPtr bg, int depth);
  5786. internal static IntPtr XCreatePixmapFromBitmapData(IntPtr display, IntPtr drawable, byte[] data, int width, int height, IntPtr fg, IntPtr bg, int depth)
  5787. {
  5788. DebugHelper.TraceWriteLine ("XCreatePixmapFromBitmapData");
  5789. return _XCreatePixmapFromBitmapData(display, drawable, data, width, height, fg, bg, depth);
  5790. }
  5791. [DllImport ("libX11", EntryPoint="XCreatePixmap")]
  5792. internal extern static IntPtr _XCreatePixmap(IntPtr display, IntPtr d, int width, int height, int depth);
  5793. internal static IntPtr XCreatePixmap(IntPtr display, IntPtr d, int width, int height, int depth)
  5794. {
  5795. DebugHelper.TraceWriteLine ("XCreatePixmap");
  5796. return _XCreatePixmap(display, d, width, height, depth);
  5797. }
  5798. [DllImport ("libX11", EntryPoint="XFreePixmap")]
  5799. internal extern static IntPtr _XFreePixmap(IntPtr display, IntPtr pixmap);
  5800. internal static IntPtr XFreePixmap(IntPtr display, IntPtr pixmap)
  5801. {
  5802. DebugHelper.TraceWriteLine ("XFreePixmap");
  5803. return _XFreePixmap(display, pixmap);
  5804. }
  5805. [DllImport ("libX11", EntryPoint="XQueryBestCursor")]
  5806. internal extern static int _XQueryBestCursor(IntPtr display, IntPtr drawable, int width, int height, out int best_width, out int best_height);
  5807. internal static int XQueryBestCursor(IntPtr display, IntPtr drawable, int width, int height, out int best_width, out int best_height)
  5808. {
  5809. DebugHelper.TraceWriteLine ("XQueryBestCursor");
  5810. return _XQueryBestCursor(display, drawable, width, height, out best_width, out best_height);
  5811. }
  5812. [DllImport ("libX11", EntryPoint="XQueryExtension")]
  5813. internal extern static int _XQueryExtension(IntPtr display, string extension_name, ref int major, ref int first_event, ref int first_error);
  5814. internal static int XQueryExtension(IntPtr display, string extension_name, ref int major, ref int first_event, ref int first_error)
  5815. {
  5816. DebugHelper.TraceWriteLine ("XQueryExtension");
  5817. return _XQueryExtension(display, extension_name, ref major, ref first_event, ref first_error);
  5818. }
  5819. [DllImport ("libX11", EntryPoint="XWhitePixel")]
  5820. internal extern static IntPtr _XWhitePixel(IntPtr display, int screen_no);
  5821. internal static IntPtr XWhitePixel(IntPtr display, int screen_no)
  5822. {
  5823. DebugHelper.TraceWriteLine ("XWhitePixel");
  5824. return _XWhitePixel(display, screen_no);
  5825. }
  5826. [DllImport ("libX11", EntryPoint="XBlackPixel")]
  5827. internal extern static IntPtr _XBlackPixel(IntPtr display, int screen_no);
  5828. internal static IntPtr XBlackPixel(IntPtr display, int screen_no)
  5829. {
  5830. DebugHelper.TraceWriteLine ("XBlackPixel");
  5831. return _XBlackPixel(display, screen_no);
  5832. }
  5833. [DllImport ("libX11", EntryPoint="XGrabServer")]
  5834. internal extern static void _XGrabServer(IntPtr display);
  5835. internal static void XGrabServer(IntPtr display)
  5836. {
  5837. DebugHelper.TraceWriteLine ("XGrabServer");
  5838. _XGrabServer(display);
  5839. }
  5840. [DllImport ("libX11", EntryPoint="XUngrabServer")]
  5841. internal extern static void _XUngrabServer(IntPtr display);
  5842. internal static void XUngrabServer(IntPtr display)
  5843. {
  5844. DebugHelper.TraceWriteLine ("XUngrabServer");
  5845. _XUngrabServer(display);
  5846. }
  5847. [DllImport ("libX11", EntryPoint="XGetWMNormalHints")]
  5848. internal extern static void _XGetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints, out IntPtr supplied_return);
  5849. internal static void XGetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints, out IntPtr supplied_return)
  5850. {
  5851. DebugHelper.TraceWriteLine ("XGetWMNormalHints");
  5852. _XGetWMNormalHints(display, window, ref hints, out supplied_return);
  5853. }
  5854. [DllImport ("libX11", EntryPoint="XSetWMNormalHints")]
  5855. internal extern static void _XSetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints);
  5856. internal static void XSetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints)
  5857. {
  5858. DebugHelper.TraceWriteLine ("XSetWMNormalHints");
  5859. _XSetWMNormalHints(display, window, ref hints);
  5860. }
  5861. [DllImport ("libX11", EntryPoint="XSetZoomHints")]
  5862. internal extern static void _XSetZoomHints(IntPtr display, IntPtr window, ref XSizeHints hints);
  5863. internal static void XSetZoomHints(IntPtr display, IntPtr window, ref XSizeHints hints)
  5864. {
  5865. DebugHelper.TraceWriteLine ("XSetZoomHints");
  5866. _XSetZoomHints(display, window, ref hints);
  5867. }
  5868. [DllImport ("libX11", EntryPoint="XSetWMHints")]
  5869. internal extern static void _XSetWMHints(IntPtr display, IntPtr window, ref XWMHints wmhints);
  5870. internal static void XSetWMHints(IntPtr display, IntPtr window, ref XWMHints wmhints)
  5871. {
  5872. DebugHelper.TraceWriteLine ("XSetWMHints");
  5873. _XSetWMHints(display, window, ref wmhints);
  5874. }
  5875. [DllImport ("libX11", EntryPoint="XGetIconSizes")]
  5876. internal extern static int _XGetIconSizes(IntPtr display, IntPtr window, out IntPtr size_list, out int count);
  5877. internal static int XGetIconSizes(IntPtr display, IntPtr window, out IntPtr size_list, out int count)
  5878. {
  5879. DebugHelper.TraceWriteLine ("XGetIconSizes");
  5880. return _XGetIconSizes(display, window, out size_list, out count);
  5881. }
  5882. [DllImport ("libX11", EntryPoint="XSetErrorHandler")]
  5883. internal extern static IntPtr _XSetErrorHandler(XErrorHandler error_handler);
  5884. internal static IntPtr XSetErrorHandler(XErrorHandler error_handler)
  5885. {
  5886. DebugHelper.TraceWriteLine ("XSetErrorHandler");
  5887. return _XSetErrorHandler(error_handler);
  5888. }
  5889. [DllImport ("libX11", EntryPoint="XGetErrorText")]
  5890. internal extern static IntPtr _XGetErrorText(IntPtr display, byte code, StringBuilder buffer, int length);
  5891. internal static IntPtr XGetErrorText(IntPtr display, byte code, StringBuilder buffer, int length)
  5892. {
  5893. DebugHelper.TraceWriteLine ("XGetErrorText");
  5894. return _XGetErrorText(display, code, buffer, length);
  5895. }
  5896. [DllImport ("libX11", EntryPoint="XInitThreads")]
  5897. internal extern static int _XInitThreads();
  5898. internal static int XInitThreads()
  5899. {
  5900. DebugHelper.TraceWriteLine ("XInitThreads");
  5901. return _XInitThreads();
  5902. }
  5903. [DllImport ("libX11", EntryPoint="XConvertSelection")]
  5904. internal extern static int _XConvertSelection(IntPtr display, IntPtr selection, IntPtr target, IntPtr property, IntPtr requestor, IntPtr time);
  5905. internal static int XConvertSelection(IntPtr display, IntPtr selection, IntPtr target, IntPtr property, IntPtr requestor, IntPtr time)
  5906. {
  5907. DebugHelper.TraceWriteLine ("XConvertSelection");
  5908. return _XConvertSelection(display, selection, target, property, requestor, time);
  5909. }
  5910. [DllImport ("libX11", EntryPoint="XGetSelectionOwner")]
  5911. internal extern static IntPtr _XGetSelectionOwner(IntPtr display, IntPtr selection);
  5912. internal static IntPtr XGetSelectionOwner(IntPtr display, IntPtr selection)
  5913. {
  5914. DebugHelper.TraceWriteLine ("XGetSelectionOwner");
  5915. return _XGetSelectionOwner(display, selection);
  5916. }
  5917. [DllImport ("libX11", EntryPoint="XSetSelectionOwner")]
  5918. internal extern static int _XSetSelectionOwner(IntPtr display, IntPtr selection, IntPtr owner, IntPtr time);
  5919. internal static int XSetSelectionOwner(IntPtr display, IntPtr selection, IntPtr owner, IntPtr time)
  5920. {
  5921. DebugHelper.TraceWriteLine ("XSetSelectionOwner");
  5922. return _XSetSelectionOwner(display, selection, owner, time);
  5923. }
  5924. [DllImport ("libX11", EntryPoint="XSetPlaneMask")]
  5925. internal extern static int _XSetPlaneMask(IntPtr display, IntPtr gc, IntPtr mask);
  5926. internal static int XSetPlaneMask(IntPtr display, IntPtr gc, IntPtr mask)
  5927. {
  5928. DebugHelper.TraceWriteLine ("XSetPlaneMask");
  5929. return _XSetPlaneMask(display, gc, mask);
  5930. }
  5931. [DllImport ("libX11", EntryPoint="XSetForeground")]
  5932. internal extern static int _XSetForeground(IntPtr display, IntPtr gc, UIntPtr foreground);
  5933. internal static int XSetForeground(IntPtr display, IntPtr gc, UIntPtr foreground)
  5934. {
  5935. DebugHelper.TraceWriteLine ("XSetForeground");
  5936. return _XSetForeground(display, gc, foreground);
  5937. }
  5938. [DllImport ("libX11", EntryPoint="XSetBackground")]
  5939. internal extern static int _XSetBackground(IntPtr display, IntPtr gc, UIntPtr background);
  5940. internal static int XSetBackground(IntPtr display, IntPtr gc, UIntPtr background)
  5941. {
  5942. DebugHelper.TraceWriteLine ("XSetBackground");
  5943. return _XSetBackground(display, gc, background);
  5944. }
  5945. [DllImport ("libX11", EntryPoint="XBell")]
  5946. internal extern static int _XBell(IntPtr display, int percent);
  5947. internal static int XBell(IntPtr display, int percent)
  5948. {
  5949. DebugHelper.TraceWriteLine ("XBell");
  5950. return _XBell(display, percent);
  5951. }
  5952. [DllImport ("libX11", EntryPoint="XChangeActivePointerGrab")]
  5953. internal extern static int _XChangeActivePointerGrab (IntPtr display, EventMask event_mask, IntPtr cursor, IntPtr time);
  5954. internal static int XChangeActivePointerGrab (IntPtr display, EventMask event_mask, IntPtr cursor, IntPtr time)
  5955. {
  5956. DebugHelper.TraceWriteLine ("XChangeActivePointerGrab");
  5957. return _XChangeActivePointerGrab (display, event_mask, cursor, time);
  5958. }
  5959. [DllImport ("libX11", EntryPoint="XFilterEvent")]
  5960. internal extern static bool _XFilterEvent(ref XEvent xevent, IntPtr window);
  5961. internal static bool XFilterEvent(ref XEvent xevent, IntPtr window)
  5962. {
  5963. DebugHelper.TraceWriteLine ("XFilterEvent");
  5964. return _XFilterEvent(ref xevent, window);
  5965. }
  5966. [DllImport ("libX11", EntryPoint="XkbSetDetectableAutoRepeat")]
  5967. internal extern static void _XkbSetDetectableAutoRepeat (IntPtr display, bool detectable, IntPtr supported);
  5968. internal static void XkbSetDetectableAutoRepeat (IntPtr display, bool detectable, IntPtr supported)
  5969. {
  5970. DebugHelper.TraceWriteLine ("XkbSetDetectableAutoRepeat");
  5971. _XkbSetDetectableAutoRepeat (display, detectable, supported);
  5972. }
  5973. [DllImport ("libX11", EntryPoint="XPeekEvent")]
  5974. internal extern static void _XPeekEvent (IntPtr display, ref XEvent xevent);
  5975. internal static void XPeekEvent (IntPtr display, ref XEvent xevent)
  5976. {
  5977. DebugHelper.TraceWriteLine ("XPeekEvent");
  5978. _XPeekEvent (display, ref xevent);
  5979. }
  5980. [DllImport ("libX11", EntryPoint="XIfEvent")]
  5981. internal extern static void _XIfEvent (IntPtr display, ref XEvent xevent, Delegate event_predicate, IntPtr arg);
  5982. internal static void XIfEvent (IntPtr display, ref XEvent xevent, Delegate event_predicate, IntPtr arg)
  5983. {
  5984. DebugHelper.TraceWriteLine ("XIfEvent");
  5985. _XIfEvent (display, ref xevent, event_predicate, arg);
  5986. }
  5987. #endregion
  5988. #else //no TRACE defined
  5989. #region Xcursor imports
  5990. [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadCursor")]
  5991. internal extern static IntPtr XcursorLibraryLoadCursor (IntPtr display, [MarshalAs (UnmanagedType.LPStr)] string name);
  5992. [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadImages")]
  5993. internal extern static IntPtr XcursorLibraryLoadImages ([MarshalAs (UnmanagedType.LPStr)] string file, IntPtr theme, int size);
  5994. [DllImport ("libXcursor", EntryPoint = "XcursorImagesDestroy")]
  5995. internal extern static void XcursorImagesDestroy (IntPtr images);
  5996. [DllImport ("libXcursor", EntryPoint = "XcursorGetDefaultSize")]
  5997. internal extern static int XcursorGetDefaultSize (IntPtr display);
  5998. [DllImport ("libXcursor", EntryPoint = "XcursorImageLoadCursor")]
  5999. internal extern static IntPtr XcursorImageLoadCursor (IntPtr display, IntPtr image);
  6000. [DllImport ("libXcursor", EntryPoint = "XcursorGetTheme")]
  6001. internal extern static IntPtr XcursorGetTheme (IntPtr display);
  6002. #endregion
  6003. #region X11 Imports
  6004. [DllImport ("libX11", EntryPoint="XOpenDisplay")]
  6005. internal extern static IntPtr XOpenDisplay(IntPtr display);
  6006. [DllImport ("libX11", EntryPoint="XCloseDisplay")]
  6007. internal extern static int XCloseDisplay(IntPtr display);
  6008. [DllImport ("libX11", EntryPoint="XSynchronize")]
  6009. internal extern static IntPtr XSynchronize(IntPtr display, bool onoff);
  6010. [DllImport ("libX11", EntryPoint="XCreateWindow")]
  6011. 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, UIntPtr valuemask, ref XSetWindowAttributes attributes);
  6012. [DllImport ("libX11", EntryPoint="XCreateSimpleWindow")]
  6013. internal extern static IntPtr XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, UIntPtr border, UIntPtr background);
  6014. [DllImport ("libX11", EntryPoint="XMapWindow")]
  6015. internal extern static int XMapWindow(IntPtr display, IntPtr window);
  6016. [DllImport ("libX11", EntryPoint="XUnmapWindow")]
  6017. internal extern static int XUnmapWindow(IntPtr display, IntPtr window);
  6018. [DllImport ("libX11", EntryPoint="XMapSubwindows")]
  6019. internal extern static int XMapSubindows(IntPtr display, IntPtr window);
  6020. [DllImport ("libX11", EntryPoint="XUnmapSubwindows")]
  6021. internal extern static int XUnmapSubwindows(IntPtr display, IntPtr window);
  6022. [DllImport ("libX11", EntryPoint="XRootWindow")]
  6023. internal extern static IntPtr XRootWindow(IntPtr display, int screen_number);
  6024. [DllImport ("libX11", EntryPoint="XNextEvent")]
  6025. internal extern static IntPtr XNextEvent(IntPtr display, ref XEvent xevent);
  6026. [DllImport ("libX11", EntryPoint="XConnectionNumber")]
  6027. internal extern static int XConnectionNumber (IntPtr display);
  6028. [DllImport ("libX11", EntryPoint="XPending")]
  6029. internal extern static int XPending (IntPtr display);
  6030. [DllImport ("libX11", EntryPoint="XSelectInput")]
  6031. internal extern static IntPtr XSelectInput(IntPtr display, IntPtr window, IntPtr mask);
  6032. [DllImport ("libX11", EntryPoint="XDestroyWindow")]
  6033. internal extern static int XDestroyWindow(IntPtr display, IntPtr window);
  6034. [DllImport ("libX11", EntryPoint="XReparentWindow")]
  6035. internal extern static int XReparentWindow(IntPtr display, IntPtr window, IntPtr parent, int x, int y);
  6036. [DllImport ("libX11", EntryPoint="XMoveResizeWindow")]
  6037. extern static int XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height);
  6038. internal static int MoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height)
  6039. {
  6040. int ret = XMoveResizeWindow (display, window, x, y, width, height);
  6041. Keyboard.MoveCurrentCaretPos ();
  6042. return ret;
  6043. }
  6044. [DllImport ("libX11", EntryPoint="XResizeWindow")]
  6045. internal extern static int XResizeWindow(IntPtr display, IntPtr window, int width, int height);
  6046. [DllImport ("libX11", EntryPoint="XGetWindowAttributes")]
  6047. internal extern static int XGetWindowAttributes(IntPtr display, IntPtr window, ref XWindowAttributes attributes);
  6048. [DllImport ("libX11", EntryPoint="XFlush")]
  6049. internal extern static int XFlush(IntPtr display);
  6050. [DllImport ("libX11", EntryPoint="XSetWMName")]
  6051. internal extern static int XSetWMName(IntPtr display, IntPtr window, ref XTextProperty text_prop);
  6052. [DllImport ("libX11", EntryPoint="XStoreName")]
  6053. internal extern static int XStoreName(IntPtr display, IntPtr window, string window_name);
  6054. [DllImport ("libX11", EntryPoint="XFetchName")]
  6055. internal extern static int XFetchName(IntPtr display, IntPtr window, ref IntPtr window_name);
  6056. [DllImport ("libX11", EntryPoint="XSendEvent")]
  6057. internal extern static int XSendEvent(IntPtr display, IntPtr window, bool propagate, IntPtr event_mask, ref XEvent send_event);
  6058. [DllImport ("libX11", EntryPoint="XQueryTree")]
  6059. 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);
  6060. [DllImport ("libX11", EntryPoint="XFree")]
  6061. internal extern static int XFree(IntPtr data);
  6062. [DllImport ("libX11", EntryPoint="XRaiseWindow")]
  6063. internal extern static int XRaiseWindow(IntPtr display, IntPtr window);
  6064. [DllImport ("libX11", EntryPoint="XLowerWindow")]
  6065. internal extern static uint XLowerWindow(IntPtr display, IntPtr window);
  6066. [DllImport ("libX11", EntryPoint="XConfigureWindow")]
  6067. internal extern static uint XConfigureWindow(IntPtr display, IntPtr window, ChangeWindowFlags value_mask, ref XWindowChanges values);
  6068. [DllImport ("libX11", EntryPoint="XInternAtom")]
  6069. internal extern static IntPtr XInternAtom(IntPtr display, string atom_name, bool only_if_exists);
  6070. [DllImport ("libX11", EntryPoint="XInternAtoms")]
  6071. internal extern static int XInternAtoms(IntPtr display, string[] atom_names, int atom_count, bool only_if_exists, IntPtr[] atoms);
  6072. [DllImport ("libX11", EntryPoint="XSetWMProtocols")]
  6073. internal extern static int XSetWMProtocols(IntPtr display, IntPtr window, IntPtr[] protocols, int count);
  6074. [DllImport ("libX11", EntryPoint="XGrabPointer")]
  6075. internal extern static int XGrabPointer(IntPtr display, IntPtr window, bool owner_events, EventMask event_mask, GrabMode pointer_mode, GrabMode keyboard_mode, IntPtr confine_to, IntPtr cursor, IntPtr timestamp);
  6076. [DllImport ("libX11", EntryPoint="XUngrabPointer")]
  6077. internal extern static int XUngrabPointer(IntPtr display, IntPtr timestamp);
  6078. [DllImport ("libX11", EntryPoint="XQueryPointer")]
  6079. 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);
  6080. [DllImport ("libX11", EntryPoint="XTranslateCoordinates")]
  6081. 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);
  6082. [DllImport ("libX11", EntryPoint="XGetGeometry")]
  6083. internal extern static bool XGetGeometry(IntPtr display, IntPtr window, out IntPtr root, out int x, out int y, out int width, out int height, out int border_width, out int depth);
  6084. [DllImport ("libX11", EntryPoint="XGetGeometry")]
  6085. internal extern static bool XGetGeometry(IntPtr display, IntPtr window, IntPtr root, out int x, out int y, out int width, out int height, IntPtr border_width, IntPtr depth);
  6086. [DllImport ("libX11", EntryPoint="XGetGeometry")]
  6087. internal extern static bool XGetGeometry(IntPtr display, IntPtr window, IntPtr root, out int x, out int y, IntPtr width, IntPtr height, IntPtr border_width, IntPtr depth);
  6088. [DllImport ("libX11", EntryPoint="XGetGeometry")]
  6089. internal extern static bool XGetGeometry(IntPtr display, IntPtr window, IntPtr root, IntPtr x, IntPtr y, out int width, out int height, IntPtr border_width, IntPtr depth);
  6090. [DllImport ("libX11", EntryPoint="XWarpPointer")]
  6091. 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);
  6092. [DllImport ("libX11", EntryPoint="XClearWindow")]
  6093. internal extern static int XClearWindow(IntPtr display, IntPtr window);
  6094. [DllImport ("libX11", EntryPoint="XClearArea")]
  6095. internal extern static int XClearArea(IntPtr display, IntPtr window, int x, int y, int width, int height, bool exposures);
  6096. // Colormaps
  6097. [DllImport ("libX11", EntryPoint="XDefaultScreenOfDisplay")]
  6098. internal extern static IntPtr XDefaultScreenOfDisplay(IntPtr display);
  6099. [DllImport ("libX11", EntryPoint="XScreenNumberOfScreen")]
  6100. internal extern static int XScreenNumberOfScreen(IntPtr display, IntPtr Screen);
  6101. [DllImport ("libX11", EntryPoint="XDefaultVisual")]
  6102. internal extern static IntPtr XDefaultVisual(IntPtr display, int screen_number);
  6103. [DllImport ("libX11", EntryPoint="XDefaultDepth")]
  6104. internal extern static uint XDefaultDepth(IntPtr display, int screen_number);
  6105. [DllImport ("libX11", EntryPoint="XDefaultScreen")]
  6106. internal extern static int XDefaultScreen(IntPtr display);
  6107. [DllImport ("libX11", EntryPoint="XDefaultColormap")]
  6108. internal extern static IntPtr XDefaultColormap(IntPtr display, int screen_number);
  6109. [DllImport ("libX11", EntryPoint="XLookupColor")]
  6110. internal extern static int XLookupColor(IntPtr display, IntPtr Colormap, string Coloranem, ref XColor exact_def_color, ref XColor screen_def_color);
  6111. [DllImport ("libX11", EntryPoint="XAllocColor")]
  6112. internal extern static int XAllocColor(IntPtr display, IntPtr Colormap, ref XColor colorcell_def);
  6113. [DllImport ("libX11", EntryPoint="XSetTransientForHint")]
  6114. internal extern static int XSetTransientForHint(IntPtr display, IntPtr window, IntPtr prop_window);
  6115. [DllImport ("libX11", EntryPoint="XChangeProperty")]
  6116. internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref MotifWmHints data, int nelements);
  6117. [DllImport ("libX11", EntryPoint="XChangeProperty")]
  6118. internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref uint value, int nelements);
  6119. [DllImport ("libX11", EntryPoint="XChangeProperty")]
  6120. internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref IntPtr value, int nelements);
  6121. [DllImport ("libX11", EntryPoint="XChangeProperty")]
  6122. internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, uint[] data, int nelements);
  6123. [DllImport ("libX11", EntryPoint="XChangeProperty")]
  6124. internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, int[] data, int nelements);
  6125. [DllImport ("libX11", EntryPoint="XChangeProperty")]
  6126. internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr[] data, int nelements);
  6127. [DllImport ("libX11", EntryPoint="XChangeProperty")]
  6128. internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr atoms, int nelements);
  6129. [DllImport ("libX11", EntryPoint="XChangeProperty", CharSet=CharSet.Ansi)]
  6130. internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, string text, int text_length);
  6131. [DllImport ("libX11", EntryPoint="XDeleteProperty")]
  6132. internal extern static int XDeleteProperty(IntPtr display, IntPtr window, IntPtr property);
  6133. // Drawing
  6134. [DllImport ("libX11", EntryPoint="XCreateGC")]
  6135. internal extern static IntPtr XCreateGC(IntPtr display, IntPtr window, IntPtr valuemask, ref XGCValues values);
  6136. [DllImport ("libX11", EntryPoint="XFreeGC")]
  6137. internal extern static int XFreeGC(IntPtr display, IntPtr gc);
  6138. [DllImport ("libX11", EntryPoint="XSetFunction")]
  6139. internal extern static int XSetFunction(IntPtr display, IntPtr gc, GXFunction function);
  6140. [DllImport ("libX11", EntryPoint="XSetLineAttributes")]
  6141. internal extern static int XSetLineAttributes(IntPtr display, IntPtr gc, int line_width, GCLineStyle line_style, GCCapStyle cap_style, GCJoinStyle join_style);
  6142. [DllImport ("libX11", EntryPoint="XDrawLine")]
  6143. internal extern static int XDrawLine(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2);
  6144. [DllImport ("libX11", EntryPoint="XDrawRectangle")]
  6145. internal extern static int XDrawRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
  6146. [DllImport ("libX11", EntryPoint="XFillRectangle")]
  6147. internal extern static int XFillRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
  6148. [DllImport ("libX11", EntryPoint="XSetWindowBackground")]
  6149. internal extern static int XSetWindowBackground(IntPtr display, IntPtr window, IntPtr background);
  6150. [DllImport ("libX11", EntryPoint="XCopyArea")]
  6151. 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);
  6152. [DllImport ("libX11", EntryPoint="XGetWindowProperty")]
  6153. internal extern static int XGetWindowProperty(IntPtr display, IntPtr window, IntPtr atom, IntPtr long_offset, IntPtr long_length, bool delete, IntPtr req_type, out IntPtr actual_type, out int actual_format, out IntPtr nitems, out IntPtr bytes_after, ref IntPtr prop);
  6154. [DllImport ("libX11", EntryPoint="XSetInputFocus")]
  6155. internal extern static int XSetInputFocus(IntPtr display, IntPtr window, RevertTo revert_to, IntPtr time);
  6156. [DllImport ("libX11", EntryPoint="XIconifyWindow")]
  6157. internal extern static int XIconifyWindow(IntPtr display, IntPtr window, int screen_number);
  6158. [DllImport ("libX11", EntryPoint="XDefineCursor")]
  6159. internal extern static int XDefineCursor(IntPtr display, IntPtr window, IntPtr cursor);
  6160. [DllImport ("libX11", EntryPoint="XUndefineCursor")]
  6161. internal extern static int XUndefineCursor(IntPtr display, IntPtr window);
  6162. [DllImport ("libX11", EntryPoint="XFreeCursor")]
  6163. internal extern static int XFreeCursor(IntPtr display, IntPtr cursor);
  6164. [DllImport ("libX11", EntryPoint="XCreateFontCursor")]
  6165. internal extern static IntPtr XCreateFontCursor(IntPtr display, CursorFontShape shape);
  6166. [DllImport ("libX11", EntryPoint="XCreatePixmapCursor")]
  6167. 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);
  6168. [DllImport ("libX11", EntryPoint="XCreatePixmapFromBitmapData")]
  6169. internal extern static IntPtr XCreatePixmapFromBitmapData(IntPtr display, IntPtr drawable, byte[] data, int width, int height, IntPtr fg, IntPtr bg, int depth);
  6170. [DllImport ("libX11", EntryPoint="XCreatePixmap")]
  6171. internal extern static IntPtr XCreatePixmap(IntPtr display, IntPtr d, int width, int height, int depth);
  6172. [DllImport ("libX11", EntryPoint="XFreePixmap")]
  6173. internal extern static IntPtr XFreePixmap(IntPtr display, IntPtr pixmap);
  6174. [DllImport ("libX11", EntryPoint="XQueryBestCursor")]
  6175. internal extern static int XQueryBestCursor(IntPtr display, IntPtr drawable, int width, int height, out int best_width, out int best_height);
  6176. [DllImport ("libX11", EntryPoint="XQueryExtension")]
  6177. internal extern static int XQueryExtension(IntPtr display, string extension_name, ref int major, ref int first_event, ref int first_error);
  6178. [DllImport ("libX11", EntryPoint="XWhitePixel")]
  6179. internal extern static IntPtr XWhitePixel(IntPtr display, int screen_no);
  6180. [DllImport ("libX11", EntryPoint="XBlackPixel")]
  6181. internal extern static IntPtr XBlackPixel(IntPtr display, int screen_no);
  6182. [DllImport ("libX11", EntryPoint="XGrabServer")]
  6183. internal extern static void XGrabServer(IntPtr display);
  6184. [DllImport ("libX11", EntryPoint="XUngrabServer")]
  6185. internal extern static void XUngrabServer(IntPtr display);
  6186. [DllImport ("libX11", EntryPoint="XGetWMNormalHints")]
  6187. internal extern static void XGetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints, out IntPtr supplied_return);
  6188. [DllImport ("libX11", EntryPoint="XSetWMNormalHints")]
  6189. internal extern static void XSetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints);
  6190. [DllImport ("libX11", EntryPoint="XSetZoomHints")]
  6191. internal extern static void XSetZoomHints(IntPtr display, IntPtr window, ref XSizeHints hints);
  6192. [DllImport ("libX11", EntryPoint="XSetWMHints")]
  6193. internal extern static void XSetWMHints(IntPtr display, IntPtr window, ref XWMHints wmhints);
  6194. [DllImport ("libX11", EntryPoint="XGetIconSizes")]
  6195. internal extern static int XGetIconSizes(IntPtr display, IntPtr window, out IntPtr size_list, out int count);
  6196. [DllImport ("libX11", EntryPoint="XSetErrorHandler")]
  6197. internal extern static IntPtr XSetErrorHandler(XErrorHandler error_handler);
  6198. [DllImport ("libX11", EntryPoint="XGetErrorText")]
  6199. internal extern static IntPtr XGetErrorText(IntPtr display, byte code, StringBuilder buffer, int length);
  6200. [DllImport ("libX11", EntryPoint="XInitThreads")]
  6201. internal extern static int XInitThreads();
  6202. [DllImport ("libX11", EntryPoint="XConvertSelection")]
  6203. internal extern static int XConvertSelection(IntPtr display, IntPtr selection, IntPtr target, IntPtr property, IntPtr requestor, IntPtr time);
  6204. [DllImport ("libX11", EntryPoint="XGetSelectionOwner")]
  6205. internal extern static IntPtr XGetSelectionOwner(IntPtr display, IntPtr selection);
  6206. [DllImport ("libX11", EntryPoint="XSetSelectionOwner")]
  6207. internal extern static int XSetSelectionOwner(IntPtr display, IntPtr selection, IntPtr owner, IntPtr time);
  6208. [DllImport ("libX11", EntryPoint="XSetPlaneMask")]
  6209. internal extern static int XSetPlaneMask(IntPtr display, IntPtr gc, IntPtr mask);
  6210. [DllImport ("libX11", EntryPoint="XSetForeground")]
  6211. internal extern static int XSetForeground(IntPtr display, IntPtr gc, UIntPtr foreground);
  6212. [DllImport ("libX11", EntryPoint="XSetBackground")]
  6213. internal extern static int XSetBackground(IntPtr display, IntPtr gc, UIntPtr background);
  6214. [DllImport ("libX11", EntryPoint="XBell")]
  6215. internal extern static int XBell(IntPtr display, int percent);
  6216. [DllImport ("libX11", EntryPoint="XChangeActivePointerGrab")]
  6217. internal extern static int XChangeActivePointerGrab (IntPtr display, EventMask event_mask, IntPtr cursor, IntPtr time);
  6218. [DllImport ("libX11", EntryPoint="XFilterEvent")]
  6219. internal extern static bool XFilterEvent(ref XEvent xevent, IntPtr window);
  6220. [DllImport ("libX11", EntryPoint="XkbSetDetectableAutoRepeat")]
  6221. internal extern static void XkbSetDetectableAutoRepeat (IntPtr display, bool detectable, IntPtr supported);
  6222. [DllImport ("libX11", EntryPoint="XPeekEvent")]
  6223. internal extern static void XPeekEvent (IntPtr display, ref XEvent xevent);
  6224. [DllImport ("libX11", EntryPoint="XIfEvent")]
  6225. internal extern static void XIfEvent (IntPtr display, ref XEvent xevent, Delegate event_predicate, IntPtr arg);
  6226. [DllImport ("libX11", EntryPoint="XGetInputFocus")]
  6227. internal extern static void XGetInputFocus (IntPtr display, out IntPtr focus, out IntPtr revert_to);
  6228. #endregion
  6229. #region Gtk/Gdk imports
  6230. [DllImport("libgdk-x11-2.0")]
  6231. internal extern static IntPtr gdk_atom_intern (string atomName, bool onlyIfExists);
  6232. [DllImport("libgtk-x11-2.0")]
  6233. internal extern static IntPtr gtk_clipboard_get (IntPtr atom);
  6234. [DllImport("libgtk-x11-2.0")]
  6235. internal extern static void gtk_clipboard_store (IntPtr clipboard);
  6236. [DllImport("libgtk-x11-2.0")]
  6237. internal extern static void gtk_clipboard_set_text (IntPtr clipboard, string text, int len);
  6238. #endregion
  6239. #endif
  6240. }
  6241. }