From: Jean-Philippe Bruyère Date: Tue, 6 Aug 2019 08:16:09 +0000 (+0200) Subject: xcb cursor, cairo push/pop group to get rid of flickering in xcb X-Git-Tag: v0.8.7~12 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=323a97ef6b6cc8c868e763ed14283b58f21d461c;p=jp%2Fcrow.git xcb cursor, cairo push/pop group to get rid of flickering in xcb --- diff --git a/Crow/Default.style b/Crow/Default.style index 5343c09f..1e017ce6 100644 --- a/Crow/Default.style +++ b/Crow/Default.style @@ -56,8 +56,8 @@ MenuItem { //Background = "vgradient|0:DimGrey|1:Black"; //Background = "Transparent"; Foreground = "LightGrey"; - //MouseEnter = "{Background=SteelBlue;}"; - //MouseLeave = "{Background=Transparent;}"; + MouseEnter = "{Background=SteelBlue;}"; + MouseLeave = "{Background=Transparent;}"; //MouseEnter = "{Background = vgradient|0:SteelBlue|1:Jet;Foreground=White;}"; //MouseLeave = "{Foreground=LightGrey;Background=Transparent;}"; SelectionBackground = "Transparent"; diff --git a/Crow/Templates/MenuItem.template b/Crow/Templates/MenuItem.template index d3321661..f6f9a9ac 100644 --- a/Crow/Templates/MenuItem.template +++ b/Crow/Templates/MenuItem.template @@ -1,5 +1,4 @@  - @@ -21,6 +20,4 @@ - - - + \ No newline at end of file diff --git a/Crow/src/Enums.cs b/Crow/src/Enums.cs index 8b90d6ea..42adab57 100644 --- a/Crow/src/Enums.cs +++ b/Crow/src/Enums.cs @@ -62,4 +62,28 @@ namespace Crow Bottom, Center, } + public enum MouseCursor + { + Arrow, + IBeam, + Crosshair, + Circle, + Hand, + Move, + Wait, + H, + V, + Top, + TopLeft, + TopRight, + Left, + Right, + BottomLeft, + Bottom, + BottomRight, + NW, + NE, + SW, + SE, + } } diff --git a/Crow/src/GraphicObjects/Label.cs b/Crow/src/GraphicObjects/Label.cs index c7bd5124..265afcb3 100644 --- a/Crow/src/GraphicObjects/Label.cs +++ b/Crow/src/GraphicObjects/Label.cs @@ -689,12 +689,12 @@ namespace Crow { base.onMouseEnter (sender, e); if (Selectable) - IFace.MouseCursor = XCursor.Text; + IFace.MouseCursor = MouseCursor.IBeam; } public override void onMouseLeave (object sender, MouseMoveEventArgs e) { base.onMouseLeave (sender, e); - IFace.MouseCursor = XCursor.Default; + IFace.MouseCursor = MouseCursor.Arrow; } protected override void onFocused (object sender, EventArgs e) { diff --git a/Crow/src/GraphicObjects/Splitter.cs b/Crow/src/GraphicObjects/Splitter.cs index e1f8e637..5b400e80 100644 --- a/Crow/src/GraphicObjects/Splitter.cs +++ b/Crow/src/GraphicObjects/Splitter.cs @@ -91,14 +91,14 @@ namespace Crow { base.onMouseEnter (sender, e); if ((Parent as GenericStack).Orientation == Orientation.Horizontal) - IFace.MouseCursor = XCursor.H; + IFace.MouseCursor = MouseCursor.H; else - IFace.MouseCursor = XCursor.V; + IFace.MouseCursor = MouseCursor.V; } public override void onMouseLeave (object sender, MouseMoveEventArgs e) { base.onMouseLeave (sender, e); - IFace.MouseCursor = XCursor.Default; + IFace.MouseCursor = MouseCursor.Arrow; } public override void onMouseDown (object sender, MouseButtonEventArgs e) { diff --git a/Crow/src/GraphicObjects/Window.cs b/Crow/src/GraphicObjects/Window.cs index 6c8f005e..a9effb88 100644 --- a/Crow/src/GraphicObjects/Window.cs +++ b/Crow/src/GraphicObjects/Window.cs @@ -296,7 +296,7 @@ namespace Crow if (!hoverBorder) { currentDirection = Direction.None; - IFace.MouseCursor = XCursor.Default; + IFace.MouseCursor = MouseCursor.Arrow; return; } @@ -333,31 +333,31 @@ namespace Crow if (currentDirection != lastDir) { switch (currentDirection) { case Direction.None: - otkgw.MouseCursor = XCursor.Default; + otkgw.MouseCursor = MouseCursor.Move; break; case Direction.N: - otkgw.MouseCursor = XCursor.V; + otkgw.MouseCursor = MouseCursor.Top; break; case Direction.S: - otkgw.MouseCursor = XCursor.V; + otkgw.MouseCursor = MouseCursor.Bottom; break; case Direction.E: - otkgw.MouseCursor = XCursor.H; + otkgw.MouseCursor = MouseCursor.Right; break; case Direction.W: - otkgw.MouseCursor = XCursor.H; + otkgw.MouseCursor = MouseCursor.Left; break; case Direction.NW: - otkgw.MouseCursor = XCursor.NW; + otkgw.MouseCursor = MouseCursor.TopLeft; break; case Direction.NE: - otkgw.MouseCursor = XCursor.NE; + otkgw.MouseCursor = MouseCursor.TopRight; break; case Direction.SW: - otkgw.MouseCursor = XCursor.SW; + otkgw.MouseCursor = MouseCursor.BottomLeft; break; case Direction.SE: - otkgw.MouseCursor = XCursor.SE; + otkgw.MouseCursor = MouseCursor.BottomRight; break; } } @@ -423,7 +423,7 @@ namespace Crow { hoverBorder = false; currentDirection = Direction.None; - IFace.MouseCursor = XCursor.Default; + IFace.MouseCursor = MouseCursor.Arrow; } protected virtual void onBorderMouseEnter (object sender, MouseMoveEventArgs e) { @@ -433,7 +433,7 @@ namespace Crow protected void butQuitPress (object sender, MouseButtonEventArgs e) { - IFace.MouseCursor = XCursor.Default; + IFace.MouseCursor = MouseCursor.Arrow; close (); } diff --git a/Crow/src/Interface.cs b/Crow/src/Interface.cs index d4376a4d..b18d1f73 100644 --- a/Crow/src/Interface.cs +++ b/Crow/src/Interface.cs @@ -185,7 +185,7 @@ namespace Crow { while (running) { Update (); - Thread.Sleep (8); + Thread.Sleep (5); } } @@ -804,13 +804,7 @@ namespace Crow if (!clipping.IsEmpty) { IsDirty = true; - for (int i = 0; i < clipping.NumRectangles; i++) - ctx.Rectangle(clipping.GetRectangle(i)); - - ctx.ClipPreserve(); - ctx.Operator = Operator.Clear; - ctx.Fill(); - ctx.Operator = Operator.Over; + ctx.PushGroup (); for (int i = GraphicTree.Count -1; i >= 0 ; i--){ Widget p = GraphicTree[i]; @@ -840,13 +834,25 @@ namespace Crow } } - #if DEBUG_CLIP_RECTANGLE +#if DEBUG_CLIP_RECTANGLE ctx.LineWidth = 1; ctx.SetSourceColor(Color.Magenta.AdjustAlpha (0.5)); for (int i = 0; i < clipping.NumRectangles; i++) ctx.Rectangle(clipping.GetRectangle(i)); ctx.Stroke (); - #endif +#endif + + ctx.PopGroupToSource (); + + for (int i = 0; i < clipping.NumRectangles; i++) + ctx.Rectangle (clipping.GetRectangle (i)); + + ctx.ClipPreserve (); + ctx.Operator = Operator.Clear; + ctx.Fill (); + ctx.Operator = Operator.Over; + + ctx.Paint (); clipping.Dispose (); clipping = new Region (); @@ -999,16 +1005,19 @@ namespace Crow } #region Mouse and Keyboard Handling - XCursor cursor = XCursor.Default; + MouseCursor cursor = MouseCursor.Arrow; public MouseState Mouse; - public XCursor MouseCursor { + public MouseCursor MouseCursor { set { + if (value == cursor) return; cursor = value; - MouseCursorChanged.Raise (this,new MouseCursorChangedEventArgs(cursor)); + if (backend != null) + backend.Cursor = cursor; + //MouseCursorChanged.Raise (this,new MouseCursorChangedEventArgs(cursor)); } } /// Processes mouse move events from the root container, this function @@ -1037,10 +1046,10 @@ namespace Crow if (DragAndDropOperation != null)//drag source cant have hover event, so move has to be handle here DragAndDropOperation.DragSource.onMouseMove (this, e); - if (HoverWidget != null) { + if (_hoverWidget != null) { resetTooltip (); //check topmost graphicobject first - Widget tmp = HoverWidget; + Widget tmp = _hoverWidget; Widget topc = null; while (tmp is Widget) { topc = tmp; @@ -1052,13 +1061,13 @@ namespace Crow while (i < idxhw) { if (!GraphicTree [i].isPopup) { if (GraphicTree [i].MouseIsIn (e.Position)) { - while (HoverWidget != null) { - HoverWidget.onMouseLeave (HoverWidget, e); - HoverWidget = HoverWidget.focusParent; + while (_hoverWidget != null) { + _hoverWidget.onMouseLeave (_hoverWidget, e); + HoverWidget = _hoverWidget.focusParent; } GraphicTree [i].checkHoverWidget (e); - HoverWidget.onMouseMove (this, e); + _hoverWidget.onMouseMove (this, e); return true; } } @@ -1066,23 +1075,22 @@ namespace Crow } } - if (HoverWidget.MouseIsIn (e.Position)) { - HoverWidget.checkHoverWidget (e); - HoverWidget.onMouseMove (this, e); + if (_hoverWidget.MouseIsIn (e.Position)) { + _hoverWidget.checkHoverWidget (e); + _hoverWidget.onMouseMove (this, e); return true; - } else { - HoverWidget.onMouseLeave (HoverWidget, e); - //seek upward from last focused graph obj's - while (HoverWidget.focusParent != null) { - HoverWidget = HoverWidget.focusParent; - if (HoverWidget.MouseIsIn (e.Position)) { - HoverWidget.checkHoverWidget (e); - HoverWidget.onMouseMove (this, e); - return true; - } else - HoverWidget.onMouseLeave (HoverWidget, e); + } + _hoverWidget.onMouseLeave (_hoverWidget, e); + //seek upward from last focused graph obj's + while (_hoverWidget.focusParent != null) { + HoverWidget = _hoverWidget.focusParent; + if (_hoverWidget.MouseIsIn (e.Position)) { + _hoverWidget.checkHoverWidget (e); + _hoverWidget.onMouseMove (this, e); + return true; } - } + _hoverWidget.onMouseLeave (_hoverWidget, e); + } } //top level graphic obj's parsing @@ -1093,7 +1101,7 @@ namespace Crow g.checkHoverWidget (e); if (g is Window) PutOnTop (g); - HoverWidget.onMouseMove (this, e); + _hoverWidget.onMouseMove (this, e); return true; } } @@ -1141,14 +1149,14 @@ namespace Crow Mouse.EnableBit ((int)button); MouseButtonEventArgs e = new MouseButtonEventArgs (button) { Mouse = Mouse }; - if (HoverWidget == null) + if (_hoverWidget == null) return false; - Widget hoverFocused = HoverWidget; + Widget hoverFocused = _hoverWidget; while (!hoverFocused.Focusable) { hoverFocused = hoverFocused.focusParent; if (hoverFocused == null) { - hoverFocused = HoverWidget; + hoverFocused = _hoverWidget; break; } } @@ -1164,9 +1172,9 @@ namespace Crow armedClickSender.onMouseClick (armedClickSender, armedClickEvtArgs); armedClickSender = null; - HoverWidget.onMouseDown(HoverWidget,new BubblingMouseButtonEventArg(e)); + _hoverWidget.onMouseDown(_hoverWidget,new BubblingMouseButtonEventArg(e)); - if (FocusedWidget == null) + if (_focusedWidget == null) return true; ActiveWidget = FocusedWidget; @@ -1187,9 +1195,9 @@ namespace Crow Mouse.SetScrollRelative (0, delta); MouseWheelEventArgs e = new MouseWheelEventArgs () { Mouse = Mouse, DeltaPrecise = delta }; - if (HoverWidget == null) + if (_hoverWidget == null) return false; - HoverWidget.onMouseWheel (this, e); + _hoverWidget.onMouseWheel (this, e); return true; } @@ -1200,8 +1208,8 @@ namespace Crow #region Tooltip handling Stopwatch tooltipTimer = new Stopwatch(); - Widget ToolTipContainer = null; - volatile bool tooltipVisible = false; + Widget ToolTipContainer; + volatile bool tooltipVisible; protected void initTooltip () { ToolTipContainer = CreateInstance ("#Crow.Tooltip.template"); @@ -1279,7 +1287,7 @@ namespace Crow ctxMenuContainer.Left = Mouse.X - 5; ctxMenuContainer.Top = Mouse.Y - 5; - HoverWidget = ctxMenuContainer; + _hoverWidget = ctxMenuContainer; ctxMenuContainer.onMouseEnter (ctxMenuContainer, new MouseMoveEventArgs (Mouse.X, Mouse.Y, 0, 0)); } #endregion diff --git a/Crow/src/MouseCursorChangedEventArgs.cs b/Crow/src/MouseCursorChangedEventArgs.cs index 9c63c11f..5e58b861 100644 --- a/Crow/src/MouseCursorChangedEventArgs.cs +++ b/Crow/src/MouseCursorChangedEventArgs.cs @@ -30,8 +30,8 @@ namespace Crow { public class MouseCursorChangedEventArgs : EventArgs { - public XCursor NewCursor; - public MouseCursorChangedEventArgs (XCursor newCursor) : base() + public MouseCursor NewCursor; + public MouseCursorChangedEventArgs (MouseCursor newCursor) : base() { NewCursor = newCursor; } diff --git a/Crow/src/backends/IBackend.cs b/Crow/src/backends/IBackend.cs index 3275205e..0cad0f4f 100644 --- a/Crow/src/backends/IBackend.cs +++ b/Crow/src/backends/IBackend.cs @@ -34,6 +34,7 @@ namespace Crow void Flush(); void ProcessEvents(); + MouseCursor Cursor { set; } bool IsDown (Key key); bool Shift { get; } bool Ctrl { get; } diff --git a/Crow/src/backends/win32/WinBackend.cs b/Crow/src/backends/win32/WinBackend.cs index 0b3f873c..50e54b93 100755 --- a/Crow/src/backends/win32/WinBackend.cs +++ b/Crow/src/backends/win32/WinBackend.cs @@ -54,8 +54,7 @@ namespace Crow.Win32 { WindowProcedureDelegate = WindowProcedure; - Rect rect = new Rect - { + Rect rect = new Rect { Left = iFace.ClientRectangle.Left, Top = iFace.ClientRectangle.Top, Right = iFace.ClientRectangle.Right, @@ -64,8 +63,7 @@ namespace Crow.Win32 { User32.Window.AdjustWindowRectEx (ref rect, 0, false, 0); - ExtendedWindowClass wc = new ExtendedWindowClass - { + ExtendedWindowClass wc = new ExtendedWindowClass { Size = ExtendedWindowClass.SizeInBytes, Style = 0, WindowProc = WindowProcedureDelegate, @@ -112,6 +110,8 @@ namespace Crow.Win32 { } } + public MouseCursor Cursor { set { throw new NotImplementedException(); } } + public bool IsDown (Key key) { return false; } diff --git a/Crow/src/backends/xcb/MouseCursor.cs b/Crow/src/backends/xcb/MouseCursor.cs new file mode 100644 index 00000000..8d29f673 --- /dev/null +++ b/Crow/src/backends/xcb/MouseCursor.cs @@ -0,0 +1,151 @@ +// +// XCursor.cs +// +// Author: +// Jean-Philippe Bruyère +// +// 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.IO; +using System.Diagnostics; +using System.Collections.Generic; + +namespace Crow +{ + public class XCursorFile + { + const uint XC_TYPE_IMG = 0xfffd0002; + + class toc + { + public uint type; + public uint subtype; + public uint pos; + + public toc(BinaryReader sr) + { + type = sr.ReadUInt32(); + subtype = sr.ReadUInt32(); + pos = sr.ReadUInt32(); + } + } + + public List Cursors = new List(); + + + static XCursorFile loadFromStream(Stream s) + { + List tocList = new List (); + XCursorFile tmp = new XCursorFile (); + + using (BinaryReader sr = new BinaryReader (s)) { + byte[] data; + //magic: CARD32 ’Xcur’ (0x58, 0x63, 0x75, 0x72) + if (new string (sr.ReadChars (4)) != "Xcur") { + Debug.WriteLine ("XCursor Load error: Wrong magic"); + return null; + } + //header: CARD32 bytes in this header + uint headerLength = sr.ReadUInt32 (); + //version: CARD32 file version number + uint version = sr.ReadUInt32 (); + //ntoc: CARD32 number of toc entries + uint nbToc = sr.ReadUInt32 (); + //toc: LISTofTOC table of contents + for (uint i = 0; i < nbToc; i++) { + tocList.Add (new toc (sr)); + } + + foreach (toc t in tocList) { + if (t.type != XC_TYPE_IMG) + continue; + + sr.BaseStream.Seek (t.pos, SeekOrigin.Begin); + tmp.Cursors.Add(imageLoad (sr)); + } + } + return tmp; + } + + public static XCursorFile Load(Interface iface, string path) + { + return loadFromStream (iface.GetStreamFromPath (path)); + } + + static XCursor imageLoad (BinaryReader sr) + { + XCursor tmp = new XCursor (); + // header: 36 Image headers are 36 bytes + uint header = sr.ReadUInt32(); + // type: 0xfffd0002 Image type is 0xfffd0002 + uint type = sr.ReadUInt32(); + // subtype: CARD32 Image subtype is the nominal size + uint subtype = sr.ReadUInt32(); + // version: 1 + uint version = sr.ReadUInt32(); + // width: CARD32 Must be less than or equal to 0x7fff + tmp.Width = sr.ReadUInt32(); + // height: CARD32 Must be less than or equal to 0x7fff + tmp.Height = sr.ReadUInt32(); + // xhot: CARD32 Must be less than or equal to width + tmp.Xhot = sr.ReadUInt32(); + // yhot: CARD32 Must be less than or equal to height + tmp.Yhot = sr.ReadUInt32(); + // delay: CARD32 Delay between animation frames in milliseconds + tmp.Delay = sr.ReadUInt32(); + // pixels: LISTofCARD32 Packed ARGB format pixels + tmp.data = sr.ReadBytes((int)(tmp.Width * tmp.Height * 4)); + return tmp; + } + } + public class XCursor + { + public static XCursor Default; + public static XCursor Cross; + public static XCursor Arrow; + public static XCursor Text; + public static XCursor SW; + public static XCursor SE; + public static XCursor NW; + public static XCursor NE; + public static XCursor N; + public static XCursor S; + public static XCursor V; + public static XCursor H; + + public uint Width; + public uint Height; + public uint Xhot; + public uint Yhot; + public uint Delay; + public byte[] data; + + public XCursor () + { + } +// public static implicit operator XCursor(XCursor xc) +// { +// return new XCursor((int)xc.Xhot, (int)xc.Yhot, (int)xc.Width, (int)xc.Height,xc.data); +// } + } +} + diff --git a/Crow/src/backends/xcb/XCBBackend.cs b/Crow/src/backends/xcb/XCBBackend.cs index 59376a8e..8464defb 100644 --- a/Crow/src/backends/xcb/XCBBackend.cs +++ b/Crow/src/backends/xcb/XCBBackend.cs @@ -24,23 +24,16 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System; -using System.Diagnostics; +using System.Collections.Generic; using System.Runtime.InteropServices; -using System.Text; namespace Crow.XCB -{ +{ using xcb_window_t = System.UInt32; - using xcb_pixmap_t = System.UInt32; - using xcb_cursor_t = System.UInt32; - using xcb_font_t = System.UInt32; using xcb_colormap_t = System.UInt32; - using xcb_atom_t = System.UInt32; - using xcb_drawable_t = System.UInt32; using xcb_visualid_t = System.UInt32; - using xcb_keysym_t = System.UInt32; using xcb_keycode_t = System.Byte; using xcb_timestamp_t = System.UInt32; @@ -137,6 +130,7 @@ namespace Crow.XCB MAPPING_NOTIFY, GE_GENERIC, } + [Flags] enum xcb_cw_t : uint { BACK_PIXMAP = 1, @@ -324,47 +318,76 @@ namespace Crow.XCB #region pinvoke XCB - [DllImportAttribute ("xcb")] + [DllImport ("xcb")] static extern IntPtr xcb_connect(string displayName, IntPtr screenNum); - [DllImportAttribute("xcb")] + [DllImport ("xcb")] static extern IntPtr xcb_get_setup(IntPtr connection); - [DllImportAttribute("xcb")] + [DllImport ("xcb")] static extern IntPtr xcb_flush(IntPtr connection); - [DllImportAttribute("xcb")] + [DllImport ("xcb")] static extern UInt32 xcb_generate_id(IntPtr connection); - [DllImportAttribute("xcb")] + [DllImport("xcb")] static extern xcb_iterator_t xcb_setup_roots_iterator(IntPtr setup); - [DllImportAttribute("xcb")] + [DllImport("xcb")] static extern xcb_iterator_t xcb_screen_allowed_depths_iterator(IntPtr scr); - [DllImportAttribute("xcb")] + [DllImport("xcb")] static extern xcb_iterator_t xcb_depth_visuals_iterator(IntPtr depth); - [DllImportAttribute("xcb")] + [DllImport("xcb")] static extern void xcb_screen_next(ref xcb_iterator_t scr_iterator); - [DllImportAttribute("xcb")] + [DllImport("xcb")] static extern void xcb_depth_next(ref xcb_iterator_t depth_iterator); - [DllImportAttribute("xcb")] + [DllImport("xcb")] static extern void xcb_visualtype_next(ref xcb_iterator_t depth_visual_iterator); - [DllImportAttribute("xcb")] + [DllImport("xcb")] static extern xcb_void_cookie_t xcb_create_window(IntPtr connection, byte depth, xcb_window_t win, UInt32 parent, Int16 x, Int16 y, UInt16 width, UInt16 height, UInt16 border, xcb_window_class_t _class, xcb_visualid_t visual, xcb_cw_t mask, IntPtr valueList); - [DllImportAttribute("xcb")] + [DllImport("xcb")] static extern xcb_void_cookie_t xcb_map_window(IntPtr conn, xcb_window_t window); - [DllImportAttribute("xcb")] + [DllImport("xcb")] static extern void xcb_disconnect(IntPtr connection); - [DllImportAttribute("xcb")] + [DllImport("xcb")] static extern IntPtr xcb_poll_for_event(IntPtr connection); + [DllImport ("xcb")] + static extern xcb_void_cookie_t xcb_change_window_attributes (IntPtr conn, xcb_window_t window, xcb_cw_t value_mask, IntPtr value_list); + + [DllImport ("xcb")]//in xcbproto + static extern xcb_void_cookie_t xcb_free_cursor (IntPtr connection, UInt32 cursor); + + //TODO: there should be a generic free method in xcb or at least xcb_free_event!! + [DllImport ("X11")] + static extern IntPtr XFree (IntPtr data); + //[DllImport ("X11")] + //static extern int XInitThreads (); + //[DllImport ("X11")] + //static extern void XLockDisplay (IntPtr display); + //[DllImport ("X11")] + //static extern void XUnlockDisplay (IntPtr display); + + #region xcb_cursor + [DllImport ("xcb-cursor")] + static extern int xcb_cursor_context_new (IntPtr conn, IntPtr screen, out IntPtr ctx); + [DllImport ("xcb-cursor", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] + static extern UInt32 xcb_cursor_load_cursor (IntPtr ctx, [MarshalAs (UnmanagedType.LPStr)]string name); + [DllImport ("xcb-cursor")] + static extern void xcb_cursor_context_free (IntPtr ctx); + + #endregion #endregion Interface iFace; IntPtr conn; + xcb_window_t win; + + IntPtr cursorCtx; + Dictionary cursors; XKB.XCBKeyboard Keyboard; @@ -376,7 +399,6 @@ namespace Crow.XCB conn = xcb_connect (null, IntPtr.Zero); - Keyboard = new XKB.XCBKeyboard (conn, iFace); xcb_iterator_t scr_it = xcb_setup_roots_iterator (xcb_get_setup (conn)); @@ -384,7 +406,7 @@ namespace Crow.XCB xcb_screen_t scr = (xcb_screen_t)Marshal.PtrToStructure (screen, typeof(xcb_screen_t)); - xcb_window_t win = xcb_generate_id (conn); + win = xcb_generate_id (conn); xcb_cw_t mask = xcb_cw_t.BACK_PIXEL | xcb_cw_t.EVENT_MASK; uint[] values = { @@ -399,15 +421,13 @@ namespace Crow.XCB ) }; - IntPtr intPtr = IntPtr.Zero; - unsafe - { - fixed(uint* pValues = values) - intPtr = new IntPtr((void *) pValues); - xcb_create_window (conn, XCB_COPY_FROM_PARENT, win, scr.root, 0,0,(ushort)iFace.ClientRectangle.Width, (ushort)iFace.ClientRectangle.Height,0, - xcb_window_class_t.INPUT_OUTPUT, scr.root_visual, mask, intPtr); - } + GCHandle hndValues = GCHandle.Alloc (values, GCHandleType.Pinned); + + xcb_create_window (conn, XCB_COPY_FROM_PARENT, win, scr.root, 0,0,(ushort)iFace.ClientRectangle.Width, (ushort)iFace.ClientRectangle.Height,0, + xcb_window_class_t.INPUT_OUTPUT, scr.root_visual, mask, hndValues.AddrOfPinnedObject()); + + hndValues.Free (); xcb_map_window (conn, win); @@ -415,7 +435,10 @@ namespace Crow.XCB IntPtr visual = findVisual (scr_it, scr.root_visual); - //loadCursors (); + if (xcb_cursor_context_new (conn, screen, out cursorCtx) < 0) + throw new Exception ("Could not initialize xcb-cursor"); + + loadCursors (); iFace.surf = new Cairo.XcbSurface (conn, win, visual, iFace.ClientRectangle.Width, iFace.ClientRectangle.Height); } @@ -424,6 +447,11 @@ namespace Crow.XCB { Keyboard.Destroy (); + foreach (xcb_window_t cur in cursors.Values) + xcb_free_cursor (conn, cur); + + xcb_cursor_context_free (cursorCtx); + xcb_disconnect (conn); } public void Flush () { @@ -468,6 +496,7 @@ namespace Crow.XCB Console.WriteLine ("unknown event"); break; } + XFree (evtPtr); } public bool IsDown (Key key) { return false; @@ -481,20 +510,52 @@ namespace Crow.XCB public bool Alt { get { return Keyboard.Alt;} } + + public MouseCursor Cursor { + set { + GCHandle hndValues = GCHandle.Alloc (cursors [value], GCHandleType.Pinned); + xcb_void_cookie_t res = xcb_change_window_attributes (conn, win, xcb_cw_t.CURSOR, hndValues.AddrOfPinnedObject ()); + hndValues.Free (); + xcb_flush (conn); + } + } #endregion + UInt32 tryGetCursor (params string[] names) + { + for (int i = 0; i < names.Length; i++) { + xcb_window_t cur = xcb_cursor_load_cursor (cursorCtx, names[i]); + if (cur != 0) + return cur; + } + return 0; + } + + void loadCursors () { + cursors = new Dictionary (); //Load cursors - XCursor.Cross = XCursorFile.Load (iFace, "#Crow.Images.Icons.Cursors.cross").Cursors [0]; - XCursor.Default = XCursorFile.Load (iFace, "#Crow.Images.Icons.Cursors.arrow").Cursors [0]; - XCursor.NW = XCursorFile.Load (iFace, "#Crow.Images.Icons.Cursors.top_left_corner").Cursors [0]; - XCursor.NE = XCursorFile.Load (iFace, "#Crow.Images.Icons.Cursors.top_right_corner").Cursors [0]; - XCursor.SW = XCursorFile.Load (iFace, "#Crow.Images.Icons.Cursors.bottom_left_corner").Cursors [0]; - XCursor.SE = XCursorFile.Load (iFace, "#Crow.Images.Icons.Cursors.bottom_right_corner").Cursors [0]; - XCursor.H = XCursorFile.Load (iFace, "#Crow.Images.Icons.Cursors.sb_h_double_arrow").Cursors [0]; - XCursor.V = XCursorFile.Load (iFace, "#Crow.Images.Icons.Cursors.sb_v_double_arrow").Cursors [0]; - XCursor.Text = XCursorFile.Load (iFace, "#Crow.Images.Icons.Cursors.ibeam").Cursors [0]; + cursors.Add (MouseCursor.Arrow, tryGetCursor("arrow", "default")); + cursors.Add (MouseCursor.IBeam, tryGetCursor ("text", "ibeam")); + cursors.Add (MouseCursor.Crosshair, tryGetCursor ("cross", "crosshair")); + cursors.Add (MouseCursor.Hand, tryGetCursor ("hand", "hand2", "hand1", "pointing_hand")); + cursors.Add (MouseCursor.Move, tryGetCursor ("move")); + cursors.Add (MouseCursor.Circle, tryGetCursor ("circle")); + cursors.Add (MouseCursor.H, tryGetCursor ("ew-resize")); + cursors.Add (MouseCursor.V, tryGetCursor ("ns-resize")); + cursors.Add (MouseCursor.NW, tryGetCursor ("nw-resize")); + cursors.Add (MouseCursor.NE, tryGetCursor ("ne-resize")); + cursors.Add (MouseCursor.SW, tryGetCursor ("sw-resize")); + cursors.Add (MouseCursor.SE, tryGetCursor ("se-resize")); + cursors.Add (MouseCursor.TopLeft, tryGetCursor ("nw-resize")); + cursors.Add (MouseCursor.Top, tryGetCursor ("n-resize")); + cursors.Add (MouseCursor.TopRight, tryGetCursor ("ne-resize")); + cursors.Add (MouseCursor.Left, tryGetCursor ("w-resize")); + cursors.Add (MouseCursor.Right, tryGetCursor ("e-resize")); + cursors.Add (MouseCursor.BottomLeft, tryGetCursor ("sw-resize")); + cursors.Add (MouseCursor.Bottom, tryGetCursor ("s-resize")); + cursors.Add (MouseCursor.BottomRight, tryGetCursor ("se-resize")); } static IntPtr findVisual (xcb_iterator_t scr_it, xcb_visualid_t visualId){ diff --git a/Crow/src/backends/xcb/XCursor.cs b/Crow/src/backends/xcb/XCursor.cs deleted file mode 100644 index 1cca510e..00000000 --- a/Crow/src/backends/xcb/XCursor.cs +++ /dev/null @@ -1,151 +0,0 @@ -// -// XCursor.cs -// -// Author: -// Jean-Philippe Bruyère -// -// 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.IO; -using System.Diagnostics; -using System.Collections.Generic; - -namespace Crow -{ - public class XCursorFile - { - const uint XC_TYPE_IMG = 0xfffd0002; - - class toc - { - public uint type; - public uint subtype; - public uint pos; - - public toc(BinaryReader sr) - { - type = sr.ReadUInt32(); - subtype = sr.ReadUInt32(); - pos = sr.ReadUInt32(); - } - } - - public List Cursors = new List(); - - - static XCursorFile loadFromStream(Stream s) - { - List tocList = new List (); - XCursorFile tmp = new XCursorFile (); - - using (BinaryReader sr = new BinaryReader (s)) { - byte[] data; - //magic: CARD32 ’Xcur’ (0x58, 0x63, 0x75, 0x72) - if (new string (sr.ReadChars (4)) != "Xcur") { - Debug.WriteLine ("XCursor Load error: Wrong magic"); - return null; - } - //header: CARD32 bytes in this header - uint headerLength = sr.ReadUInt32 (); - //version: CARD32 file version number - uint version = sr.ReadUInt32 (); - //ntoc: CARD32 number of toc entries - uint nbToc = sr.ReadUInt32 (); - //toc: LISTofTOC table of contents - for (uint i = 0; i < nbToc; i++) { - tocList.Add (new toc (sr)); - } - - foreach (toc t in tocList) { - if (t.type != XC_TYPE_IMG) - continue; - - sr.BaseStream.Seek (t.pos, SeekOrigin.Begin); - tmp.Cursors.Add(imageLoad (sr)); - } - } - return tmp; - } - - public static XCursorFile Load(Interface iface, string path) - { - return loadFromStream (iface.GetStreamFromPath (path)); - } - - static XCursor imageLoad(BinaryReader sr) - { - XCursor tmp = new XCursor(); - // header: 36 Image headers are 36 bytes - uint header = sr.ReadUInt32(); - // type: 0xfffd0002 Image type is 0xfffd0002 - uint type = sr.ReadUInt32(); - // subtype: CARD32 Image subtype is the nominal size - uint subtype = sr.ReadUInt32(); - // version: 1 - uint version = sr.ReadUInt32(); - // width: CARD32 Must be less than or equal to 0x7fff - tmp.Width = sr.ReadUInt32(); - // height: CARD32 Must be less than or equal to 0x7fff - tmp.Height = sr.ReadUInt32(); - // xhot: CARD32 Must be less than or equal to width - tmp.Xhot = sr.ReadUInt32(); - // yhot: CARD32 Must be less than or equal to height - tmp.Yhot = sr.ReadUInt32(); - // delay: CARD32 Delay between animation frames in milliseconds - tmp.Delay = sr.ReadUInt32(); - // pixels: LISTofCARD32 Packed ARGB format pixels - tmp.data = sr.ReadBytes((int)(tmp.Width * tmp.Height * 4)); - return tmp; - } - } - public class XCursor - { - public static XCursor Default; - public static XCursor Cross; - public static XCursor Arrow; - public static XCursor Text; - public static XCursor SW; - public static XCursor SE; - public static XCursor NW; - public static XCursor NE; - public static XCursor N; - public static XCursor S; - public static XCursor V; - public static XCursor H; - - public uint Width; - public uint Height; - public uint Xhot; - public uint Yhot; - public uint Delay; - public byte[] data; - - public XCursor () - { - } -// public static implicit operator MouseCursor(XCursor xc) -// { -// return new MouseCursor((int)xc.Xhot, (int)xc.Yhot, (int)xc.Width, (int)xc.Height,xc.data); -// } - } -} - diff --git a/Crow/src/backends/xlib/X11Structs.cs b/Crow/src/backends/xlib/X11Structs.cs index 5e43e006..79b26180 100644 --- a/Crow/src/backends/xlib/X11Structs.cs +++ b/Crow/src/backends/xlib/X11Structs.cs @@ -27,15 +27,12 @@ // NOT COMPLETE using System; -using System.ComponentModel; -using System.Collections; -using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading; -using System.Reflection; // X11 Version -namespace Crow.XLib { +namespace Crow.XLib +{ // // In the structures below, fields of type long are mapped to IntPtr. // This will work on all platforms where sizeof(long)==sizeof(void*), which diff --git a/Crow/src/backends/xlib/XLibBackend.cs b/Crow/src/backends/xlib/XLibBackend.cs index 111296e3..a8d62e06 100644 --- a/Crow/src/backends/xlib/XLibBackend.cs +++ b/Crow/src/backends/xlib/XLibBackend.cs @@ -32,42 +32,42 @@ namespace Crow.XLib public class XLibBackend : IBackend { #region pinvoke - [DllImportAttribute("X11")] + [DllImport("X11")] static extern int XInitThreads(); - [DllImportAttribute("X11")] + [DllImport("X11")] internal static extern IntPtr XOpenDisplay(IntPtr displayName); - [DllImportAttribute("X11")] + [DllImport("X11")] internal static extern IntPtr XCloseDisplay(IntPtr disp); - [DllImportAttribute("X11")] + [DllImport("X11")] static extern Int32 XDefaultScreen(IntPtr disp); - [DllImportAttribute("X11")] + [DllImport("X11")] static extern IntPtr XDefaultRootWindow(IntPtr disp); - [DllImportAttribute("X11")] + [DllImport("X11")] static extern UInt32 XDefaultDepth (IntPtr disp, Int32 screen); - [DllImportAttribute("X11")] + [DllImport("X11")] static extern IntPtr XDefaultVisual(IntPtr disp, Int32 screen); - [DllImportAttribute("X11")] + [DllImport("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")] + [DllImport("X11")] static extern IntPtr XCreatePixmap(IntPtr disp, IntPtr rootWindow, UInt32 width, UInt32 height, UInt32 depth); - [DllImportAttribute("X11")] + [DllImport("X11")] static extern IntPtr XFreePixmap(IntPtr disp, IntPtr pixmap); - [DllImportAttribute("X11")] + [DllImport("X11")] static extern IntPtr XFree(IntPtr data); - [DllImportAttribute("X11")] + [DllImport("X11")] static extern Int32 XSelectInput(IntPtr disp, IntPtr win, EventMask eventMask); - [DllImportAttribute("X11")] + [DllImport("X11")] static extern Int32 XMapWindow(IntPtr disp, IntPtr win); - [DllImportAttribute("X11")] + [DllImport("X11")] static extern int XPending (IntPtr disp); - [DllImportAttribute("X11")] + [DllImport("X11")] static extern IntPtr XNextEvent(IntPtr disp, ref XEvent xevent); - [DllImportAttribute("X11")] + [DllImport("X11")] static extern Int32 XSync(IntPtr disp, int discard); - [DllImportAttribute("X11")] + [DllImport("X11")] static extern int XConnectionNumber(IntPtr disp); - [DllImportAttribute("X11")] + [DllImport("X11")] static extern IntPtr XSetErrorHandler(XErrorHandler error_handler); #endregion @@ -181,6 +181,7 @@ namespace Crow.XLib throw new NotImplementedException (); } } + public MouseCursor Cursor { set { throw new NotImplementedException (); } } #endregion int HandleError (IntPtr display, ref XErrorEvent error_event) diff --git a/CrowIDE/src/CrowIDE.cs b/CrowIDE/src/CrowIDE.cs index d0b640ff..d66a3a37 100644 --- a/CrowIDE/src/CrowIDE.cs +++ b/CrowIDE/src/CrowIDE.cs @@ -20,17 +20,8 @@ // along with this program. If not, see . using System; -using Crow; -using System.Reflection; -using System.Collections.Generic; -using System.Collections; -using System.Xml.Serialization; using System.IO; using Crow.IML; -using System.Xml; -using System.Linq; -using Crow.Coding; -using System.Threading; namespace Crow.Coding { diff --git a/CrowIDE/src/Editors/CodeBuffer/TextEditor.cs b/CrowIDE/src/Editors/CodeBuffer/TextEditor.cs index 21459406..011086be 100644 --- a/CrowIDE/src/Editors/CodeBuffer/TextEditor.cs +++ b/CrowIDE/src/Editors/CodeBuffer/TextEditor.cs @@ -461,12 +461,12 @@ namespace Crow.Text public override void onMouseEnter (object sender, MouseMoveEventArgs e) { base.onMouseEnter (sender, e); - IFace.MouseCursor = XCursor.Text; + IFace.MouseCursor = MouseCursor.IBeam; } public override void onMouseLeave (object sender, MouseMoveEventArgs e) { base.onMouseLeave (sender, e); - IFace.MouseCursor = XCursor.Default; + IFace.MouseCursor = MouseCursor.Arrow; } public override void onMouseMove (object sender, MouseMoveEventArgs e) { diff --git a/CrowIDE/src/Editors/SourceEditor.cs b/CrowIDE/src/Editors/SourceEditor.cs index 86e0bdbf..5c6e48a2 100644 --- a/CrowIDE/src/Editors/SourceEditor.cs +++ b/CrowIDE/src/Editors/SourceEditor.cs @@ -923,14 +923,14 @@ namespace Crow.Coding { base.onMouseEnter (sender, e); if (e.X - ScreenCoordinates(Slot).X < leftMargin + ClientRectangle.X) - IFace.MouseCursor = XCursor.Default; + IFace.MouseCursor = MouseCursor.Arrow; else - IFace.MouseCursor = XCursor.Text; + IFace.MouseCursor = MouseCursor.IBeam; } public override void onMouseLeave (object sender, MouseMoveEventArgs e) { base.onMouseLeave (sender, e); - IFace.MouseCursor = XCursor.Default; + IFace.MouseCursor = MouseCursor.Arrow; } public override void onMouseMove (object sender, MouseMoveEventArgs e) { @@ -942,9 +942,9 @@ namespace Crow.Coding if (!e.Mouse.IsButtonDown (MouseButton.Left)) { if (mouseLocalPos.X < leftMargin) - IFace.MouseCursor = XCursor.Default; + IFace.MouseCursor = MouseCursor.Arrow; else - IFace.MouseCursor = XCursor.Text; + IFace.MouseCursor = MouseCursor.IBeam; return; } diff --git a/CrowIDE/src/Project.cs b/CrowIDE/src/Project.cs index a3ffa636..c916095b 100644 --- a/CrowIDE/src/Project.cs +++ b/CrowIDE/src/Project.cs @@ -507,9 +507,9 @@ namespace Crow.Coding { } foreach (ProjectReference pr in flattenNodes.OfType ()) { Project p = solution.Projects.FirstOrDefault (pp => pp.ProjectGuid == pr.ProjectGUID); - if (p == null) - throw new Exception ("referenced project not found"); - p.GetStyling (); + if (p != null) + //throw new Exception ("referenced project not found"); + p.GetStyling (); } //TODO:get styling from referenced assemblies diff --git a/CrowIDE/src/Solution.cs b/CrowIDE/src/Solution.cs index c6b1fbc1..e69cc5e8 100644 --- a/CrowIDE/src/Solution.cs +++ b/CrowIDE/src/Solution.cs @@ -102,10 +102,9 @@ namespace Crow.Coding{ Styling = new Dictionary (); if (StartupProject != null) StartupProject.GetStyling (); -// StylingContainers = new List (); -// foreach (string k in Styling.Keys) { -// StylingContainers.Add (new StyleContainer (k, Styling [k])); -// } + StylingContainers = new List (); + foreach (string k in Styling.Keys) + StylingContainers.Add (new StyleContainer (k, Styling [k])); foreach (ImlProjectItem pf in openedItems.OfType()) { pf.SignalEditorOfType (); } diff --git a/CrowIDE/ui/DockWindows/winStyleView.crow b/CrowIDE/ui/DockWindows/winStyleView.crow index a86343e4..9cdbec71 100644 --- a/CrowIDE/ui/DockWindows/winStyleView.crow +++ b/CrowIDE/ui/DockWindows/winStyleView.crow @@ -10,7 +10,7 @@