| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246 |
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- // Copyright (c) 2004 Novell, Inc.
- //
- // Authors:
- // Peter Bartok [email protected]
- //
- //
- // NOT COMPLETE
- using System;
- using System.Threading;
- using System.Drawing;
- using System.ComponentModel;
- using System.Collections;
- using System.Diagnostics;
- using System.Runtime.InteropServices;
- /// X11 Version
- namespace System.Windows.Forms {
- internal class XplatUIX11 : XplatUIDriver {
- #region Local Variables
- private static XplatUIX11 instance;
- private static int ref_count;
- private static bool themes_enabled;
- private static IntPtr DisplayHandle; // X11 handle to display
- private static IntPtr root_window; // Handle of the root window for the screen/display
- private static IntPtr FosterParent; // Container to hold child windows until their parent exists
- private static int wm_protocols; // X Atom
- private static int wm_delete_window; // X Atom
- private static IntPtr async_method;
- private static uint default_colormap; // X Colormap ID
- internal static Keys key_state;
- internal static MouseButtons mouse_state;
- internal static Point mouse_position;
- internal static bool grab_confined; // Is the current grab (if any) confined to grab_area?
- internal static IntPtr grab_hwnd; // The window that is grabbed
- internal static Rectangle grab_area; // The area the current grab is confined to
- internal static bool is_visible;
- private static Hashtable handle_data;
- private Queue message_queue;
- private ArrayList timer_list;
- private Thread timer_thread;
- private AutoResetEvent timer_wait;
- private static readonly EventMask SelectInputMask = EventMask.ButtonPressMask |
- EventMask.ButtonReleaseMask |
- EventMask.KeyPressMask |
- EventMask.KeyReleaseMask |
- EventMask.EnterWindowMask |
- EventMask.LeaveWindowMask |
- EventMask.ExposureMask |
- EventMask.PointerMotionMask |
- EventMask.VisibilityChangeMask |
- EventMask.StructureNotifyMask;
- #endregion // Local Variables
- internal override Keys ModifierKeys {
- get {
- return key_state;
- }
- }
- internal override MouseButtons MouseButtons {
- get {
- return mouse_state;
- }
- }
- internal override Point MousePosition {
- get {
- return mouse_position;
- }
- }
- internal override bool DropTarget {
- get {
- return false;
- }
- set {
- if (value) {
- throw new NotImplementedException("Need to figure out D'n'D for X11");
- }
- }
- }
- #region Constructor & Destructor
- // This is always called from a locked context
- private XplatUIX11() {
- // Handle singleton stuff first
- ref_count=0;
- message_queue = new Queue ();
- ArrayList timers = new ArrayList ();
- timer_list = ArrayList.Synchronized (timers);
- // Now regular initialization
- SetDisplay(XOpenDisplay(IntPtr.Zero));
- }
- ~XplatUIX11() {
- lock (this) {
- if (DisplayHandle!=IntPtr.Zero) {
- XCloseDisplay(DisplayHandle);
- DisplayHandle=IntPtr.Zero;
- }
- }
- }
- #endregion // Constructor & Destructor
- #region Singleton Specific Code
- public static XplatUIX11 GetInstance() {
- lock (typeof (XplatUIX11)) {
- if (instance==null) {
- instance=new XplatUIX11();
- }
- ref_count++;
- }
- return instance;
- }
- public int Reference {
- get {
- return ref_count;
- }
- }
- #endregion
- #region Public Static Methods
- internal override IntPtr InitializeDriver() {
- lock (this) {
- if (DisplayHandle==IntPtr.Zero) {
- DisplayHandle=XOpenDisplay(IntPtr.Zero);
- key_state=Keys.None;
- mouse_state=MouseButtons.None;
- mouse_position=Point.Empty;
- }
- }
- return IntPtr.Zero;
- }
- internal static void SetDisplay(IntPtr display_handle) {
- if (display_handle != IntPtr.Zero) {
- if (FosterParent != IntPtr.Zero) {
- XDestroyWindow(DisplayHandle, FosterParent);
- }
- if (DisplayHandle != IntPtr.Zero) {
- XCloseDisplay(DisplayHandle);
- }
- DisplayHandle=display_handle;
- // Create a few things
- key_state = Keys.None;
- mouse_state = MouseButtons.None;
- mouse_position = Point.Empty;
- root_window = XRootWindow(display_handle, 0);
- default_colormap = XDefaultColormap(display_handle, 0);
- // Create the foster parent
- FosterParent=XCreateSimpleWindow(display_handle, root_window, 0, 0, 1, 1, 4, 0, 0);
- if (FosterParent==IntPtr.Zero) {
- Console.WriteLine("XplatUIX11 Constructor failed to create FosterParent");
- }
- // Prepare for shutdown
- wm_protocols=XInternAtom(display_handle, "WM_PROTOCOLS", false);
- wm_delete_window=XInternAtom(display_handle, "WM_DELETE_WINDOW", false);
- handle_data = new Hashtable ();
- }
- }
- internal override void ShutdownDriver(IntPtr token) {
- lock (this) {
- if (DisplayHandle!=IntPtr.Zero) {
- XCloseDisplay(DisplayHandle);
- DisplayHandle=IntPtr.Zero;
- }
- }
- }
- internal void Version() {
- Console.WriteLine("Xplat version $revision: $");
- }
- internal override void Exit() {
- Console.WriteLine("XplatUIX11.Exit");
- }
- internal override void GetDisplaySize(out Size size) {
- XWindowAttributes attributes=new XWindowAttributes();
- lock (this) {
- XGetWindowAttributes(DisplayHandle, XRootWindow(DisplayHandle, 0), ref attributes);
- }
- size = new Size(attributes.width, attributes.height);
- }
- internal override void EnableThemes() {
- themes_enabled=true;
- }
- internal override IntPtr CreateWindow(CreateParams cp) {
- IntPtr WindowHandle;
- IntPtr ParentHandle;
- int X;
- int Y;
- int Width;
- int Height;
- int BorderWidth;
- int protocols;
- ParentHandle=cp.Parent;
- X=cp.X;
- Y=cp.Y;
- Width=cp.Width;
- Height=cp.Height;
- BorderWidth=0;
- if (Width<1) Width=1;
- if (Height<1) Height=1;
- lock (this) {
- if (ParentHandle==IntPtr.Zero) {
- if ((cp.Style & (int)WindowStyles.WS_CHILD)!=0) {
- // We need to use our foster parent window until
- // this poor child gets it's parent assigned
- ParentHandle=FosterParent;
- } else {
- if (X<1) X=50;
- if (Y<1) Y=50;
- BorderWidth=4;
- ParentHandle=XRootWindow(DisplayHandle, 0);
- }
- }
- WindowHandle=XCreateSimpleWindow(DisplayHandle, ParentHandle, X, Y, Width, Height, BorderWidth, 0, 0);
- XMapWindow(DisplayHandle, WindowHandle);
- XSelectInput(DisplayHandle, WindowHandle, SelectInputMask);
- is_visible=true;
- protocols=wm_delete_window;
- XSetWMProtocols(DisplayHandle, WindowHandle, ref protocols, 1);
- }
- return(WindowHandle);
- }
- internal override IntPtr CreateWindow(IntPtr Parent, int X, int Y, int Width, int Height) {
- CreateParams create_params = new CreateParams();
- create_params.Caption = "";
- create_params.X = X;
- create_params.Y = Y;
- create_params.Width = Width;
- create_params.Height = Height;
- create_params.ClassName=XplatUI.DefaultClassName;
- create_params.ClassStyle = 0;
- create_params.ExStyle=0;
- create_params.Parent=IntPtr.Zero;
- create_params.Param=0;
- return CreateWindow(create_params);
- }
- internal override void DestroyWindow(IntPtr handle) {
- lock (this) {
- HandleData data = (HandleData) handle_data [handle];
- if (data != null) {
- data.Dispose ();
- handle_data [handle] = null;
- }
- }
- }
- internal override void RefreshWindow(IntPtr handle) {
- XEvent xevent = new XEvent();
- IntPtr root;
- int border_width;
- int depth;
- int x;
- int y;
- int width;
- int height;
- lock (this) {
- // We need info about our window to generate the expose
- XGetGeometry(DisplayHandle, handle, out root, out x, out y,
- out width, out height, out border_width, out depth);
- xevent.type=XEventName.Expose;
- xevent.ExposeEvent.display=DisplayHandle;
- xevent.ExposeEvent.window=handle;
- xevent.ExposeEvent.x=0;
- xevent.ExposeEvent.y=0;
- xevent.ExposeEvent.width=width;
- xevent.ExposeEvent.height=height;
- XSendEvent(DisplayHandle, handle, false, EventMask.ExposureMask, ref xevent);
- XFlush(DisplayHandle);
- }
- }
- internal override void SetWindowBackground(IntPtr handle, Color color) {
- uint backcolor;
- // backcolor = ((uint)(color.ToArgb() & 0xff0000)>>16) | (uint)(color.ToArgb() & 0xff00) | (uint)((color.ToArgb() & 0xff) << 16);
- backcolor = ((uint)(color.ToArgb() & 0xff0000)) | (uint)(color.ToArgb() & 0xff00) | (uint)((color.ToArgb() & 0xff) );
- lock (this) {
- XSetWindowBackground(DisplayHandle, handle, backcolor);
- }
- }
- [MonoTODO("Add support for internal table of windows/DCs for looking up paint area and cleanup")]
- internal override PaintEventArgs PaintEventStart(IntPtr handle) {
- PaintEventArgs paint_event;
- HandleData data = (HandleData) handle_data [handle];
- if (data == null) {
- throw new Exception ("null data on paint event start: " + handle);
- }
- data.DeviceContext = Graphics.FromHwnd (handle);
- paint_event = new PaintEventArgs((Graphics)data.DeviceContext, data.InvalidArea);
- return paint_event;
- }
- internal override void PaintEventEnd(IntPtr handle) {
- HandleData data = (HandleData) handle_data [handle];
- if (data == null)
- throw new Exception ("null data on PaintEventEnd");
- data.ClearInvalidArea ();
- Graphics g = (Graphics) data.DeviceContext;
- g.Flush ();
- g.Dispose ();
- }
- internal override void SetWindowPos(IntPtr handle, int x, int y, int width, int height) {
- // X requires a sanity check for width & height; otherwise it dies
- if (width < 1) {
- width = 1;
- }
- if (height < 1) {
- height = 1;
- }
- lock (this) {
- XMoveResizeWindow(DisplayHandle, handle, x, y, width, height);
- }
- return;
- }
- internal override void GetWindowPos(IntPtr handle, out int x, out int y, out int width, out int height, out int client_width, out int client_height) {
- IntPtr root;
- int border_width;
- int depth;
- lock (this) {
-
- XGetGeometry(DisplayHandle, handle, out root, out x,
- out y, out width, out height, out border_width, out depth);
- }
- client_width = width;
- client_height = height;
- return;
- }
- internal override void Activate(IntPtr handle) {
- lock (this) {
- // Not sure this is the right method, but we don't use ICs either...
- XRaiseWindow(DisplayHandle, handle);
- }
- return;
- }
- internal override void Invalidate(IntPtr handle, Rectangle rc, bool clear) {
- XEvent xevent = new XEvent();
- xevent.type=XEventName.Expose;
- xevent.ExposeEvent.display=DisplayHandle;
- xevent.ExposeEvent.window=handle;
- xevent.ExposeEvent.count=0;
- lock (this) {
- if (clear) {
- // Need to clear the whole window, so we force a redraw for the whole window
- XWindowAttributes attributes=new XWindowAttributes();
- // We need info about our window to generate the expose
- XGetWindowAttributes(DisplayHandle, handle, ref attributes);
- xevent.ExposeEvent.x=0;
- xevent.ExposeEvent.y=0;
- xevent.ExposeEvent.width=attributes.width;
- xevent.ExposeEvent.height=attributes.height;
- } else {
- xevent.ExposeEvent.x=rc.Left;
- xevent.ExposeEvent.y=rc.Top;
- xevent.ExposeEvent.width=rc.Width;
- xevent.ExposeEvent.height=rc.Height;
- }
- XSendEvent(DisplayHandle, handle, false, EventMask.ExposureMask, ref xevent);
- // Flush is not needed, invalidate does not guarantee an immediate effect
- }
- }
- internal override IntPtr DefWndProc(ref Message msg) {
- #if not
- switch (msg.Msg) {
- case (int)Msg.WM_PAINT: {
- IntPtr gc;
- if (msg.Hwnd!=IntPtr.Zero) {
- gc=XCreateGC(DisplayHandle, msg.Hwnd, 0, IntPtr.Zero);
- XSetBackground(DisplayHandle, gc, this.BackColor.ToArgb());
- XFreeGC(DisplayHandle, gc);
- }
- break;
- }
- }
- #endif
- #if debug
- Console.WriteLine("XplatUIX11.DefWndProc");
- #endif
- return IntPtr.Zero;
- }
- internal override void HandleException(Exception e) {
- StackTrace st = new StackTrace(e);
- Console.WriteLine("Exception '{0}'", e.Message+st.ToString());
- Console.WriteLine("{0}{1}", e.Message, st.ToString());
- }
- internal override void DoEvents() {
- Console.WriteLine("XplatUIX11.DoEvents");
- }
- internal override bool PeekMessage(ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags) {
- Console.WriteLine("XplatUIX11.PeekMessage");
- return true;
- }
- private void CreateKeyBoardMsg (XEvent xevent, ref MSG msg)
- {
- IntPtr buffer = Marshal.AllocHGlobal(24);
- XKeySym keysym;
- string keys;
- int len;
- msg.wParam = IntPtr.Zero;
- lock (this) {
- len = XLookupString(ref xevent, buffer, 24, out keysym, IntPtr.Zero);
- }
- if ((keysym==XKeySym.XK_Control_L) || (keysym==XKeySym.XK_Control_R)) {
- if (xevent.type==XEventName.KeyPress) {
- key_state |= Keys.Control;
- } else {
- key_state &= ~Keys.Control;
- }
- }
- if ((keysym==XKeySym.XK_Shift_L) || (keysym==XKeySym.XK_Shift_R)) {
- if (xevent.type==XEventName.KeyPress) {
- key_state |= Keys.Shift;
- } else {
- key_state &= ~Keys.Shift;
- }
- }
- if (len>0) /* String is not zero terminated*/
- Marshal.WriteByte (buffer, len, 0);
- keys=Marshal.PtrToStringAuto(buffer);
- for (int i = 0; i < KeyMapping.Length; i++) {
- if (KeyMapping[i].X11Key == keysym) {
- msg.wParam = (IntPtr) KeyMapping[i].Win32Key;
- Console.WriteLine("Got special key {0} {1:x} ", keysym, keysym);
- break;
- }
- }
- if ((msg.wParam == IntPtr.Zero) && (keys.Length>0)) {
- char[] keychars;
- keychars=keys.ToCharArray(0, 1);
- msg.wParam=(IntPtr)keychars[0];
- Console.WriteLine("Got key {0} {1:x} ", keysym, keysym);
- }
- Marshal.FreeHGlobal (buffer);
- msg.lParam = (IntPtr) 1;
- }
- private IntPtr GetMousewParam(int Delta) {
- int result = 0;
- if ((mouse_state & MouseButtons.Left) != 0) {
- result |= (int)MsgButtons.MK_LBUTTON;
- }
- if ((mouse_state & MouseButtons.Middle) != 0) {
- result |= (int)MsgButtons.MK_MBUTTON;
- }
- if ((mouse_state & MouseButtons.Right) != 0) {
- result |= (int)MsgButtons.MK_RBUTTON;
- }
- if ((key_state & Keys.Control) != 0) {
- result |= (int)MsgButtons.MK_CONTROL;
- }
- if ((key_state & Keys.Shift) != 0) {
- result |= (int)MsgButtons.MK_SHIFT;
- }
- result |= Delta << 16;
- return (IntPtr)result;
- }
- // The message_queue should be locked when this is called
- private void UpdateMessageQueue ()
- {
- int pending;
- lock (this) {
- pending = XPending (DisplayHandle);
- }
-
- while (pending > 0) {
- XEvent xevent = new XEvent ();
- lock (this) {
- XNextEvent (DisplayHandle, ref xevent);
- }
- switch (xevent.type) {
- case XEventName.Expose:
- HandleData data = (HandleData) handle_data [xevent.AnyEvent.window];
- if (data == null) {
- data = new HandleData ();
- handle_data [xevent.AnyEvent.window] = data;
- }
-
- data.AddToInvalidArea (xevent.ExposeEvent.x, xevent.ExposeEvent.y,
- xevent.ExposeEvent.width, xevent.ExposeEvent.height);
-
- if (!data.HasExpose) {
- message_queue.Enqueue (xevent);
- data.HasExpose = true;
- }
- break;
- default:
- message_queue.Enqueue (xevent);
- break;
- }
- lock (this) {
- pending = XPending (DisplayHandle);
- }
- }
- }
- internal override bool GetMessage(ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax) {
- XEvent xevent;
- lock (message_queue) {
- if (message_queue.Count > 0) {
- xevent = (XEvent) message_queue.Dequeue ();
- } else {
- UpdateMessageQueue ();
- if (message_queue.Count > 0) {
- xevent = (XEvent) message_queue.Dequeue ();
- } else {
- msg.hwnd= IntPtr.Zero;
- msg.message = Msg.WM_ENTERIDLE;
- return true;
- }
- }
- }
- msg.hwnd=xevent.AnyEvent.window;
- switch(xevent.type) {
- case XEventName.KeyPress: {
- msg.message = Msg.WM_KEYDOWN;
- CreateKeyBoardMsg (xevent, ref msg);
- break;
- }
- case XEventName.KeyRelease: {
- msg.message=Msg.WM_KEYUP;
- CreateKeyBoardMsg (xevent, ref msg);
- break;
- }
- case XEventName.ButtonPress: {
- switch(xevent.ButtonEvent.button) {
- case 1: {
- mouse_state |= MouseButtons.Left;
- msg.message=Msg.WM_LBUTTONDOWN;
- msg.wParam=GetMousewParam(0);
- break;
- }
- case 2: {
- mouse_state |= MouseButtons.Middle;
- msg.message=Msg.WM_MBUTTONDOWN;
- msg.wParam=GetMousewParam(0);
- break;
- }
- case 3: {
- mouse_state |= MouseButtons.Right;
- msg.message=Msg.WM_RBUTTONDOWN;
- msg.wParam=GetMousewParam(0);
- break;
- }
- case 4: {
- msg.message=Msg.WM_MOUSEWHEEL;
- msg.wParam=GetMousewParam(120);
- break;
- }
- case 5: {
- msg.message=Msg.WM_MOUSEWHEEL;
- msg.wParam=GetMousewParam(-120);
- break;
- }
- }
- msg.lParam=(IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
- mouse_position.X=xevent.ButtonEvent.x;
- mouse_position.Y=xevent.ButtonEvent.y;
- break;
- }
- case XEventName.ButtonRelease: {
- switch(xevent.ButtonEvent.button) {
- case 1: {
- mouse_state &= ~MouseButtons.Left;
- msg.message=Msg.WM_LBUTTONUP;
- msg.wParam=GetMousewParam(0);
- break;
- }
- case 2: {
- mouse_state &= ~MouseButtons.Middle;
- msg.message=Msg.WM_MBUTTONUP;
- msg.wParam=GetMousewParam(0);
- break;
- }
- case 3: {
- mouse_state &= ~MouseButtons.Right;
- msg.message=Msg.WM_RBUTTONUP;
- msg.wParam=GetMousewParam(0);
- break;
- }
- case 4: {
- return true;
- }
- case 5: {
- return true;
- }
- }
- msg.lParam=(IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
- mouse_position.X=xevent.ButtonEvent.x;
- mouse_position.Y=xevent.ButtonEvent.y;
- break;
- }
- case XEventName.MotionNotify: {
- msg.message=Msg.WM_MOUSEMOVE;
- msg.wParam=GetMousewParam(0);
- msg.lParam=(IntPtr) (xevent.MotionEvent.y << 16 | xevent.MotionEvent.x);
- mouse_position.X=xevent.MotionEvent.x;
- mouse_position.Y=xevent.MotionEvent.y;
- break;
- }
- case XEventName.EnterNotify: {
- if (xevent.CrossingEvent.mode != NotifyMode.NotifyNormal) {
- return true;
- }
- msg.message=Msg.WM_MOUSE_ENTER;
- break;
- }
- case XEventName.LeaveNotify: {
- if (xevent.CrossingEvent.mode != NotifyMode.NotifyNormal) {
- return true;
- }
- msg.message=Msg.WM_MOUSE_LEAVE;
- break;
- }
- case XEventName.ConfigureNotify: {
- msg.message=Msg.WM_WINDOWPOSCHANGED;
- msg.wParam=IntPtr.Zero;
- msg.lParam=IntPtr.Zero;
- break;
- }
- case XEventName.Expose: {
- msg.message=Msg.WM_PAINT;
- msg.wParam=IntPtr.Zero;
- msg.lParam=IntPtr.Zero;
- break;
- }
- case XEventName.DestroyNotify: {
- msg.message=Msg.WM_DESTROY;
- msg.wParam=IntPtr.Zero;
- msg.lParam=IntPtr.Zero;
- break;
- }
- case XEventName.ClientMessage: {
- if (xevent.ClientMessageEvent.message_type == async_method) {
- GCHandle handle = (GCHandle)xevent.ClientMessageEvent.ptr1;
- AsyncMethodData data = (AsyncMethodData) handle.Target;
- AsyncMethodResult result = data.Result.Target as AsyncMethodResult;
- object ret = data.Method.DynamicInvoke (data.Args);
- if (result != null)
- result.Complete (ret);
- handle.Free ();
- } else {
- msg.message=Msg.WM_QUIT;
- msg.wParam=IntPtr.Zero;
- msg.lParam=IntPtr.Zero;
- return false;
- }
- break;
- }
- case XEventName.TimerNotify: {
- xevent.TimerNotifyEvent.handler (this, EventArgs.Empty);
- break;
- }
-
- default: {
- msg.message = Msg.WM_NULL;
- break;
- }
- }
- NativeWindow.WndProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
- return true;
- }
- internal override bool TranslateMessage(ref MSG msg) {
- return true;
- }
- internal override bool DispatchMessage(ref MSG msg) {
- return true;
- }
- internal override bool SetZOrder(IntPtr hWnd, IntPtr AfterhWnd, bool Top, bool Bottom) {
- if (Top) {
- XRaiseWindow(DisplayHandle, hWnd);
- return true;
- } else if (!Bottom) {
- XWindowChanges values = new XWindowChanges();
- values.sibling = AfterhWnd;
- values.stack_mode = StackMode.Below;
- XConfigureWindow(DisplayHandle, hWnd, ChangeWindowFlags.CWStackMode, ref values);
- } else {
- XLowerWindow(DisplayHandle, hWnd);
- return true;
- }
- return false;
- }
- internal override bool Text(IntPtr handle, string text) {
- #if notdef
- XTextProperty property = new XTextProperty();
- property.encoding=
- XSetWMName(DisplayHandle, handle, ref property);
- #else
- lock (this) {
- XStoreName(DisplayHandle, handle, text);
- }
- #endif
- return true;
- }
- internal override bool GetText(IntPtr handle, out string text) {
- IntPtr textptr;
- textptr = IntPtr.Zero;
- lock (this) {
- XFetchName(DisplayHandle, handle, ref textptr);
- }
- if (textptr != IntPtr.Zero) {
- text = Marshal.PtrToStringAnsi(textptr);
- XFree(textptr);
- return true;
- } else {
- text = "";
- return false;
- }
- }
- internal override bool SetVisible(IntPtr handle, bool visible) {
- lock (this) {
- if (visible) {
- XMapWindow(DisplayHandle, handle);
- is_visible=true;
- } else {
- XUnmapWindow(DisplayHandle, handle);
- is_visible=false;
- }
- }
- return true;
- }
- internal override bool IsVisible(IntPtr handle) {
- return is_visible;
- }
- internal override IntPtr SetParent(IntPtr handle, IntPtr parent) {
- XWindowAttributes attributes=new XWindowAttributes();
- lock (this) {
- XGetWindowAttributes(DisplayHandle, handle, ref attributes);
- XReparentWindow(DisplayHandle, handle, parent, attributes.x, attributes.y);
- }
- return IntPtr.Zero;
- }
- internal override IntPtr GetParent(IntPtr handle) {
- IntPtr Root;
- IntPtr Parent;
- IntPtr Children;
- int ChildCount;
- Root=IntPtr.Zero;
- Parent=IntPtr.Zero;
- Children=IntPtr.Zero;
- ChildCount=0;
- lock (this) {
- XQueryTree(DisplayHandle, handle, ref Root, ref Parent, ref Children, ref ChildCount);
- }
- if (Children!=IntPtr.Zero) {
- lock (this) {
- XFree(Children);
- }
- }
- return Parent;
- }
- internal override void GrabWindow(IntPtr hWnd, IntPtr confine_hwnd) {
- if (confine_hwnd != IntPtr.Zero) {
- XWindowAttributes attributes = new XWindowAttributes();
- lock (this) {
- XGetWindowAttributes(DisplayHandle, confine_hwnd, ref attributes);
- }
- grab_area.X = attributes.x;
- grab_area.Y = attributes.y;
- grab_area.Width = attributes.width;
- grab_area.Height = attributes.height;
- grab_confined = true;
- }
- grab_hwnd = hWnd;
- lock (this) {
- XGrabPointer(DisplayHandle, hWnd, false,
- EventMask.ButtonPressMask | EventMask.ButtonMotionMask |
- EventMask.ButtonReleaseMask | EventMask.PointerMotionMask,
- GrabMode.GrabModeAsync, GrabMode.GrabModeAsync, confine_hwnd, 0, 0);
- }
- }
- internal override void GrabInfo(out IntPtr hWnd, out bool GrabConfined, out Rectangle GrabArea) {
- hWnd = grab_hwnd;
- GrabConfined = grab_confined;
- GrabArea = grab_area;
- }
- internal override void ReleaseWindow(IntPtr hWnd) {
- lock (this) {
- XUngrabPointer(DisplayHandle, 0);
- grab_hwnd = IntPtr.Zero;
- grab_confined = false;
- }
- }
- internal override bool CalculateWindowRect(IntPtr hWnd, ref Rectangle ClientRect, int Style, bool HasMenu, out Rectangle WindowRect) {
- WindowRect = new Rectangle(ClientRect.Left, ClientRect.Top, ClientRect.Width, ClientRect.Height);
- return true;
- }
- internal override void SetCursorPos(IntPtr handle, int x, int y) {
- lock (this) {
- XWarpPointer(DisplayHandle, IntPtr.Zero, (handle!=IntPtr.Zero) ? handle : IntPtr.Zero, 0, 0, 0, 0, x, y);
- }
- }
- internal override void GetCursorPos(IntPtr handle, out int x, out int y) {
- IntPtr root;
- IntPtr child;
- int root_x;
- int root_y;
- int win_x;
- int win_y;
- int keys_buttons;
- lock (this) {
- XQueryPointer(DisplayHandle, (handle!=IntPtr.Zero) ? handle : root_window,
- out root, out child, out root_x, out root_y,
- out win_x, out win_y, out keys_buttons);
- }
- if (handle != IntPtr.Zero) {
- x = win_x;
- y = win_y;
- } else {
- x = root_x;
- y = root_y;
- }
- }
- internal override void ScreenToClient(IntPtr handle, ref int x, ref int y)
- {
- int dest_x_return;
- int dest_y_return;
- IntPtr child;
- lock (this) {
- XTranslateCoordinates (DisplayHandle, root_window,
- handle, x, y, out dest_x_return, out dest_y_return, out child);
- }
- x = dest_x_return;
- y = dest_y_return;
- }
- internal override void SendAsyncMethod (AsyncMethodData method)
- {
- XEvent xevent = new XEvent ();
-
- xevent.type = XEventName.ClientMessage;
- xevent.ClientMessageEvent.display = DisplayHandle;
- xevent.ClientMessageEvent.window = IntPtr.Zero;
- xevent.ClientMessageEvent.message_type = async_method;
- xevent.ClientMessageEvent.format = 32;
- xevent.ClientMessageEvent.ptr1 = (IntPtr) GCHandle.Alloc (method);
- lock (message_queue) {
- message_queue.Enqueue (xevent);
- }
- }
- internal void TimerProc ()
- {
- while (true) {
- int next_fire = -1;
- ArrayList fire_list = new ArrayList ();
- DateTime now = DateTime.Now;
- for (int i = 0; i < timer_list.Count; i++) {
- Timer timer = (Timer) timer_list [i];
-
- if (timer.Enabled && timer.Expires <= now) {
- XEvent xevent = new XEvent ();
- xevent.type = XEventName.TimerNotify;
- xevent.AnyEvent.window = IntPtr.Zero;
- xevent.TimerNotifyEvent.handler = new EventHandler (timer.TickHandler);
- fire_list.Add (xevent);
- timer.Update (now);
- }
- int next = (int) (timer.Expires.AddMilliseconds (timer.Interval) - now).TotalMilliseconds;
- if (i == 0 || next < next_fire)
- next_fire = next;
- }
- // Everything is copied to a list and then to the queue so we
- // don't lock the queue while calculating all the times
- if (fire_list.Count > 0) {
- lock (message_queue) {
- foreach (object obj in fire_list) {
- message_queue.Enqueue (obj);
- }
- }
- }
- if (next_fire < Timer.Minimum)
- next_fire = Timer.Minimum;
- timer_wait.WaitOne (next_fire, true);
- }
- }
- internal override void SetTimer (Timer timer)
- {
- timer_list.Add (timer);
- if (timer_thread == null) {
- ThreadStart thread_start = new ThreadStart (TimerProc);
- timer_thread = new Thread (thread_start);
- timer_thread.IsBackground = true;
- timer_wait = new AutoResetEvent (true);
- timer_thread.Start();
- }
- }
- internal override void KillTimer (Timer timer)
- {
- timer_list.Remove (timer);
- }
- // Santa's little helper
- static void Where()
- {
- Console.WriteLine("Here: {0}", new StackTrace().ToString());
- }
- #endregion // Public Static Methods
- internal struct X11ToWin32KeyMapping {
- internal XKeySym X11Key;
- internal XplatUIWin32.VirtualKeys Win32Key;
- internal X11ToWin32KeyMapping (XKeySym x11, XplatUIWin32.VirtualKeys win32)
- {
- X11Key = x11;
- Win32Key = win32;
- }
- }
- /* X11 to Win32 VK mapping */
- static readonly X11ToWin32KeyMapping[] KeyMapping = new X11ToWin32KeyMapping[]
- {
- /* Cursor navigation*/
- new X11ToWin32KeyMapping (XKeySym.XK_Left, XplatUIWin32.VirtualKeys.VK_LEFT),
- new X11ToWin32KeyMapping (XKeySym.XK_Right, XplatUIWin32.VirtualKeys.VK_RIGHT),
- new X11ToWin32KeyMapping (XKeySym.XK_Up, XplatUIWin32.VirtualKeys.VK_UP),
- new X11ToWin32KeyMapping (XKeySym.XK_Down, XplatUIWin32.VirtualKeys.VK_DOWN),
- new X11ToWin32KeyMapping (XKeySym.XK_Page_Up, XplatUIWin32.VirtualKeys.VK_PRIOR),
- new X11ToWin32KeyMapping (XKeySym.XK_Page_Down, XplatUIWin32.VirtualKeys.VK_NEXT),
- new X11ToWin32KeyMapping (XKeySym.XK_End, XplatUIWin32.VirtualKeys.VK_END),
- new X11ToWin32KeyMapping (XKeySym.XK_Home, XplatUIWin32.VirtualKeys.VK_HOME),
- /* Modifiers*/
- new X11ToWin32KeyMapping (XKeySym.XK_Shift_R, XplatUIWin32.VirtualKeys.VK_SHIFT),
- new X11ToWin32KeyMapping (XKeySym.XK_Shift_L, XplatUIWin32.VirtualKeys.VK_SHIFT),
- new X11ToWin32KeyMapping (XKeySym.XK_Control_R, XplatUIWin32.VirtualKeys.VK_CONTROL),
- new X11ToWin32KeyMapping (XKeySym.XK_Control_L, XplatUIWin32.VirtualKeys.VK_CONTROL),
- /* Others */
- new X11ToWin32KeyMapping (XKeySym.XK_Return, XplatUIWin32.VirtualKeys.VK_RETURN),
- new X11ToWin32KeyMapping (XKeySym.XK_Tab, XplatUIWin32.VirtualKeys.VK_TAB),
- new X11ToWin32KeyMapping (XKeySym.XK_Menu, XplatUIWin32.VirtualKeys.VK_MENU),
- new X11ToWin32KeyMapping (XKeySym.XK_BackSpace, XplatUIWin32.VirtualKeys.VK_BACK),
- new X11ToWin32KeyMapping (XKeySym.XK_Clear, XplatUIWin32.VirtualKeys.VK_CLEAR),
-
- };
-
- #region X11 Imports
- [DllImport ("libX11.so", EntryPoint="XOpenDisplay")]
- internal extern static IntPtr XOpenDisplay(IntPtr display);
- [DllImport ("libX11.so", EntryPoint="XCloseDisplay")]
- internal extern static void XCloseDisplay(IntPtr display);
- [DllImport ("libX11.so", EntryPoint="XCreateWindow")]
- 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, IntPtr attributes);
- [DllImport ("libX11.so", EntryPoint="XCreateSimpleWindow")]
- internal extern static IntPtr XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, int border, int background);
- [DllImport ("libX11.so", EntryPoint="XMapWindow")]
- internal extern static int XMapWindow(IntPtr display, IntPtr window);
- [DllImport ("libX11.so", EntryPoint="XUnmapWindow")]
- internal extern static int XUnmapWindow(IntPtr display, IntPtr window);
- [DllImport ("libX11.so", EntryPoint="XRootWindow")]
- internal extern static IntPtr XRootWindow(IntPtr display, int screen_number);
- [DllImport ("libX11.so", EntryPoint="XNextEvent")]
- internal extern static IntPtr XNextEvent(IntPtr display, ref XEvent xevent);
- [DllImport ("libX11.so")]
- internal extern static int XPending (IntPtr diplay);
- [DllImport ("libX11.so")]
- internal extern static bool XCheckWindowEvent (IntPtr display, IntPtr window, EventMask mask, ref XEvent xevent);
- [DllImport ("libX11.so")]
- internal extern static bool XCheckMaskEvent (IntPtr display, EventMask mask, ref XEvent xevent);
- [DllImport ("libX11.so", EntryPoint="XSelectInput")]
- internal extern static IntPtr XSelectInput(IntPtr display, IntPtr window, EventMask mask);
- [DllImport ("libX11.so", EntryPoint="XLookupString")]
- internal extern static int XLookupString(ref XEvent xevent, IntPtr buffer, int num_bytes, out XKeySym keysym, IntPtr status);
- [DllImport ("libX11.so", EntryPoint="XDestroyWindow")]
- internal extern static int XDestroyWindow(IntPtr display, IntPtr window);
- [DllImport ("libX11.so", EntryPoint="XReparentWindow")]
- internal extern static int XReparentWindow(IntPtr display, IntPtr window, IntPtr parent, int x, int y);
- [DllImport ("libX11.so", EntryPoint="XMoveResizeWindow")]
- internal extern static int XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height);
- [DllImport ("libX11.so", EntryPoint="XResizeWindow")]
- internal extern static int XResizeWindow(IntPtr display, IntPtr window, int width, int height);
- [DllImport ("libX11.so", EntryPoint="XGetWindowAttributes")]
- internal extern static int XGetWindowAttributes(IntPtr display, IntPtr window, ref XWindowAttributes attributes);
- [DllImport ("libX11.so", EntryPoint="XFlush")]
- internal extern static int XFlush(IntPtr display);
- [DllImport ("libX11.so", EntryPoint="XSetWMName")]
- internal extern static int XSetWMName(IntPtr display, IntPtr window, ref XTextProperty text_prop);
- [DllImport ("libX11.so", EntryPoint="XStoreName")]
- internal extern static int XStoreName(IntPtr display, IntPtr window, string window_name);
- [DllImport ("libX11.so", EntryPoint="XFetchName")]
- internal extern static int XFetchName(IntPtr display, IntPtr window, ref IntPtr window_name);
- [DllImport ("libX11.so", EntryPoint="XSendEvent")]
- internal extern static int XSendEvent(IntPtr display, IntPtr window, bool propagate, EventMask event_mask, ref XEvent send_event);
- [DllImport ("libX11.so", EntryPoint="XQueryTree")]
- internal extern static int XQueryTree(IntPtr display, IntPtr window, ref IntPtr root_return, ref IntPtr parent_return, ref IntPtr children_return, ref int nchildren_return);
- [DllImport ("libX11.so", EntryPoint="XFree")]
- internal extern static int XFree(IntPtr data);
- [DllImport ("libX11.so", EntryPoint="XRaiseWindow")]
- internal extern static int XRaiseWindow(IntPtr display, IntPtr window);
- [DllImport ("libX11.so", EntryPoint="XLowerWindow")]
- internal extern static uint XLowerWindow(IntPtr display, IntPtr window);
- [DllImport ("libX11.so", EntryPoint="XConfigureWindow")]
- internal extern static uint XConfigureWindow(IntPtr display, IntPtr window, ChangeWindowFlags value_mask, ref XWindowChanges values);
- [DllImport ("libX11.so", EntryPoint="XInternAtom")]
- internal extern static int XInternAtom(IntPtr display, string atom_name, bool only_if_exists);
- [DllImport ("libX11.so", EntryPoint="XSetWMProtocols")]
- internal extern static int XSetWMProtocols(IntPtr display, IntPtr window, ref int protocols, int count);
- [DllImport ("libX11.so", EntryPoint="XGrabPointer")]
- internal extern static int XGrabPointer(IntPtr display, IntPtr window, bool owner_events, EventMask event_mask, GrabMode pointer_mode, GrabMode keyboard_mode, IntPtr confine_to, uint cursor, uint timestamp);
- [DllImport ("libX11.so", EntryPoint="XUngrabPointer")]
- internal extern static int XUngrabPointer(IntPtr display, uint timestamp);
- [DllImport ("libX11.so", EntryPoint="XQueryPointer")]
- 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);
- [DllImport ("libX11.so", EntryPoint="XTranslateCoordinates")]
- 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);
- [DllImport ("libX11.so", EntryPoint="XGetGeometry")]
- 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);
- [DllImport ("libX11.so", EntryPoint="XAllocColor")]
- internal extern static int XAllocColor(IntPtr display, uint Colormap, ref XColor colorcell_def);
- [DllImport ("libX11.so", EntryPoint="XGetStandardColormap")]
- internal extern static int XGetStandardColormap(IntPtr display, IntPtr window, ref XStandardColormap cmap_info, Atom property);
- [DllImport ("libX11.so", EntryPoint="XSetRGBColormaps")]
- internal extern static int XSetRGBColormaps(IntPtr display, IntPtr window, ref XStandardColormap cmap_info, int count, Atom property);
- [DllImport ("libX11.so", EntryPoint="XInstallColormap")]
- internal extern static int XInstallColormap(IntPtr display, uint cmap);
- [DllImport ("libX11.so", EntryPoint="XDefaultColormap")]
- internal extern static uint XDefaultColormap(IntPtr display, int screen_number);
- [DllImport ("libX11.so", EntryPoint="XDefaultDepth")]
- internal extern static uint XDefaultDepth(IntPtr display, int screen_number);
- [DllImport ("libX11.so", EntryPoint="XDefaultVisual")]
- internal extern static uint XDefaultVisual(IntPtr display, int screen_number);
- [DllImport ("libX11.so", EntryPoint="XSetWindowColormap")]
- internal extern static uint XSetWindowColormap(IntPtr display, IntPtr window, uint cmap);
- [DllImport ("libX11.so", EntryPoint="XWarpPointer")]
- 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);
- // Drawing
- [DllImport ("libX11.so", EntryPoint="XCreateGC")]
- internal extern static IntPtr XCreateGC(IntPtr display, IntPtr window, int valuemask, IntPtr values);
- [DllImport ("libX11.so", EntryPoint="XFreeGC")]
- internal extern static int XFreeGC(IntPtr display, IntPtr gc);
- [DllImport ("libX11.so", EntryPoint="XSetWindowBackground")]
- internal extern static int XSetWindowBackground(IntPtr display, IntPtr window, uint background);
- #endregion
- }
- }
|