aboutsummaryrefslogtreecommitdiffstatsci
path: root/src/backends/XLibBackend.cs
diff options
context:
space:
mode:
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>2018-11-21 18:48:52 +0100
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>2018-11-21 18:48:52 +0100
commit4db409fdff013e3e4249d567e4d6fdb0ee877256 (patch)
tree3b985c0941fda237f60b2e5f9a63382327159fb9 /src/backends/XLibBackend.cs
parenta1dca1431f685020df843162b805edee11e1929c (diff)
xcb backend
Diffstat (limited to 'src/backends/XLibBackend.cs')
-rw-r--r--src/backends/XLibBackend.cs221
1 files changed, 221 insertions, 0 deletions
diff --git a/src/backends/XLibBackend.cs b/src/backends/XLibBackend.cs
new file mode 100644
index 00000000..11f44ebd
--- /dev/null
+++ b/src/backends/XLibBackend.cs
@@ -0,0 +1,221 @@
+//
+// XLibBackend.cs
+//
+// Author:
+// Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace Crow.XLIB
+{
+ public class XLibBackend : IBackend
+ {
+ #region pinvoke
+ [DllImportAttribute("X11")]
+ static extern int XInitThreads();
+ [DllImportAttribute("X11")]
+ static extern IntPtr XOpenDisplay(IntPtr displayName);
+ [DllImportAttribute("X11")]
+ static extern IntPtr XCloseDisplay(IntPtr disp);
+ [DllImportAttribute("X11")]
+ static extern Int32 XDefaultScreen(IntPtr disp);
+ [DllImportAttribute("X11")]
+ static extern IntPtr XDefaultRootWindow(IntPtr disp);
+ [DllImportAttribute("X11")]
+ static extern UInt32 XDefaultDepth (IntPtr disp, Int32 screen);
+ [DllImportAttribute("X11")]
+ static extern IntPtr XDefaultVisual(IntPtr disp, Int32 screen);
+ [DllImportAttribute("X11")]
+ static extern IntPtr XCreateSimpleWindow(IntPtr disp, IntPtr rootWindow, Int32 x, Int32 y, UInt32 width, UInt32 height,
+ UInt32 borderWidth, IntPtr border, IntPtr background);
+ [DllImportAttribute("X11")]
+ static extern IntPtr XCreatePixmap(IntPtr disp, IntPtr rootWindow, UInt32 width, UInt32 height, UInt32 depth);
+ [DllImportAttribute("X11")]
+ static extern IntPtr XFreePixmap(IntPtr disp, IntPtr pixmap);
+ [DllImportAttribute("X11")]
+ static extern IntPtr XFree(IntPtr data);
+ [DllImportAttribute("X11")]
+ static extern Int32 XSelectInput(IntPtr disp, IntPtr win, EventMask eventMask);
+ [DllImportAttribute("X11")]
+ static extern Int32 XMapWindow(IntPtr disp, IntPtr win);
+ [DllImportAttribute("X11")]
+ static extern int XPending (IntPtr disp);
+ [DllImportAttribute("X11")]
+ static extern IntPtr XNextEvent(IntPtr disp, ref XEvent xevent);
+ [DllImportAttribute("X11")]
+ static extern Int32 XSync(IntPtr disp, int discard);
+ [DllImportAttribute("X11")]
+ static extern int XConnectionNumber(IntPtr disp);
+ [DllImportAttribute("X11")]
+ static extern IntPtr XSetErrorHandler(XErrorHandler error_handler);
+
+ [DllImport ("libX11")]
+ static extern void XDisplayKeycodes (IntPtr disp, out int min, out int max);
+ [DllImport ("libX11")]
+ static extern IntPtr XGetKeyboardMapping (IntPtr disp, byte first_keycode, int keycode_count,
+ out int keysyms_per_keycode_return);
+ [DllImport ("libX11")]
+ unsafe static extern byte* XGetModifierMapping (IntPtr disp);
+ [DllImport ("libX11")]
+ static extern uint XKeycodeToKeysym (IntPtr display, int keycode, int index);
+ #endregion
+
+ IntPtr xDisp, xwinHnd, xDefaultRootWin, xDefaultVisual;
+ UInt32 xDefaultDepth;
+ Int32 xScreen;
+ XErrorHandler errorHnd;
+
+ Interface iFace;
+
+ #region IBackend implementation
+
+ public void Init (Interface _iFace)
+ {
+ iFace = _iFace;
+ XInitThreads ();
+ xDisp = XOpenDisplay(IntPtr.Zero);
+ if (xDisp == IntPtr.Zero)
+ throw new NotSupportedException("[XLib] Failed to open display.");
+
+ xScreen = XDefaultScreen(xDisp);
+
+ xDefaultRootWin = XDefaultRootWindow (xDisp);
+ xDefaultVisual = XDefaultVisual (xDisp, xScreen);
+ xDefaultDepth = XDefaultDepth (xDisp, xScreen);
+
+ xwinHnd = XCreateSimpleWindow (xDisp, xDefaultRootWin,
+ 0, 0, (uint)iFace.ClientRectangle.Width, (uint)iFace.ClientRectangle.Height, 0, IntPtr.Zero, IntPtr.Zero);
+ if (xwinHnd == IntPtr.Zero)
+ throw new NotSupportedException("[XLib] Failed to create window.");
+
+ XSelectInput (xDisp, xwinHnd, EventMask.ExposureMask |
+ EventMask.KeyPressMask | EventMask.KeyReleaseMask |
+ EventMask.PointerMotionMask | EventMask.ButtonPressMask | EventMask.ButtonReleaseMask);
+
+ XMapWindow (xDisp, xwinHnd);
+
+ iFace.surf = new Cairo.XlibSurface (xDisp, xwinHnd, xDefaultVisual, iFace.ClientRectangle.Width, iFace.ClientRectangle.Height);
+
+ errorHnd = new XErrorHandler (HandleError);
+ XSetErrorHandler (errorHnd);
+
+ int min_keycode, max_keycode, keysyms_per_keycode;
+
+ XDisplayKeycodes (xDisp, out min_keycode, out max_keycode);
+ IntPtr ksp = XGetKeyboardMapping (xDisp, (byte) min_keycode,
+ max_keycode + 1 - min_keycode, out keysyms_per_keycode);
+ XFree (ksp);
+
+ unsafe {
+ byte* modmap_unmanaged = XGetModifierMapping (xDisp);
+ int nummodmap = 0;
+ int* ptr = (int*)modmap_unmanaged;
+ nummodmap = ptr [0];
+
+ for (int i = 0; i< nummodmap; i++) {
+ Console.WriteLine(modmap_unmanaged[i+4]);
+ }
+ XFree ((IntPtr)modmap_unmanaged);
+ }
+ }
+
+ public void CleanUp ()
+ {
+ XCloseDisplay (xDisp);
+ }
+ public void Flush () {
+ XSync (xDisp, 0);
+ }
+ public void ProcessEvents ()
+ {
+ if (XPending (xDisp) > 0) {
+ XEvent xevent = new XEvent ();
+ XNextEvent (xDisp, ref xevent);
+
+ switch (xevent.type) {
+ case XEventName.Expose:
+ iFace.ProcessResize (new Rectangle (0, 0, xevent.ExposeEvent.width, xevent.ExposeEvent.height));
+ break;
+ case XEventName.KeyPress:
+ iFace.ProcessKeyDown (xevent.KeyEvent.keycode);
+
+ /*int min_keycode, max_keycode, keysyms_per_keycode;
+ XLib.NativeMethods.XDisplayKeycodes (xDisp, out min_keycode, out max_keycode);
+
+ IntPtr ksp = XLib.NativeMethods.XGetKeyboardMapping (xDisp, (byte)min_keycode,
+ max_keycode + 1 - min_keycode, out keysyms_per_keycode);
+ XLib.NativeMethods.XFree (ksp);*/
+
+ uint keySym;
+ keySym = XKeycodeToKeysym (xDisp, xevent.KeyEvent.keycode, 0);
+ char c = (char)keySym;
+
+ Debug.WriteLine ("keycode:{0}; keysym:{1}; char:{2}", xevent.KeyEvent.keycode, keySym, c);
+ break;
+ case XEventName.KeyRelease:
+ iFace.ProcessKeyUp (xevent.KeyEvent.keycode);
+ //Debug.WriteLine ("keypress: {0}", xevent.KeyEvent.keycode);
+ break;
+ case XEventName.MotionNotify:
+ //Debug.WriteLine ("motion: ({0},{1})", xevent.MotionEvent.x, xevent.MotionEvent.y);
+ iFace.ProcessMouseMove (xevent.MotionEvent.x, xevent.MotionEvent.y);
+ break;
+ case XEventName.ButtonPress:
+ //Debug.WriteLine ("button press: {0}", xevent.ButtonEvent.button);
+ if (xevent.ButtonEvent.button == 4)
+ iFace.ProcessMouseWheelChanged (Interface.WheelIncrement);
+ else if(xevent.ButtonEvent.button == 5)
+ iFace.ProcessMouseWheelChanged (-Interface.WheelIncrement);
+ else
+ iFace.ProcessMouseButtonDown (xevent.ButtonEvent.button - 1);
+ break;
+ case XEventName.ButtonRelease:
+ //Debug.WriteLine ("button release: {0}", xevent.ButtonEvent.button);
+ iFace.ProcessMouseButtonUp (xevent.ButtonEvent.button - 1);
+ break;
+
+ }
+ }
+ }
+
+ #endregion
+
+ int HandleError (IntPtr display, ref XErrorEvent error_event)
+ {
+ /*if (ErrorExceptions)
+ throw new X11Exception (error_event.display, error_event.resourceid,
+ error_event.serial, error_event.error_code,
+ error_event.request_code, error_event.minor_code);
+ else
+ Console.WriteLine ("X11 Error encountered: {0}{1}\n",
+ X11Exception.GetMessage(error_event.display, error_event.resourceid,
+ error_event.serial, error_event.error_code,
+ error_event.request_code, error_event.minor_code),
+ WhereString());*/
+ Debug.WriteLine ("XERROR {0}", error_event.error_code);
+ return 0;
+ }
+ }
+}
+