/// <summary> /// <para>Constructs a new <see cref="T:Xsharp.InputOnlyWidget"/> /// instance underneath a specified parent widget.</para> /// </summary> /// /// <param name="parent"> /// <para>The parent of the new widget.</para> /// </param> /// /// <param name="x"> /// <para>The X co-ordinate of the top-left corner of /// the new widget.</para> /// </param> /// /// <param name="y"> /// <para>The Y co-ordinate of the top-left corner of /// the new widget.</para> /// </param> /// /// <param name="width"> /// <para>The width of the new widget.</para> /// </param> /// /// <param name="height"> /// <para>The height of the new widget.</para> /// </param> /// /// <exception cref="T:System.ArgumentNullException"> /// <para>Raised if <paramref name="parent"/> is <see langword="null"/>. /// </para> /// </exception> /// /// <exception cref="T:Xsharp.XException"> /// <para>Raised if <paramref name="x"/>, <paramref name="y"/>, /// <paramref name="width"/>, or <paramref name="height"/> are /// out of range.</para> /// </exception> /// /// <exception cref="T.Xsharp.XInvalidOperationException"> /// <para>Raised if <paramref name="parent"/> is disposed or the /// root window.</para> /// </exception> public InputOnlyWidget(Widget parent, int x, int y, int width, int height) : base(GetDisplay(parent, false), GetScreen(parent), DrawableKind.InputOnlyWidget, parent) { bool ok = false; try { // Validate the position and size. if(x < -32768 || x > 32767 || y < -32768 || y > 32767) { throw new XException(S._("X_InvalidPosition")); } if(width < 1 || width > 32767 || height < 1 || height > 32767 || !ValidateSize(width, height)) { throw new XException(S._("X_InvalidSize")); } // Set the initial position and size of the widget. this.x = x; this.y = y; this.width = width; this.height = height; this.focusable = true; // Lock down the display and create the window handle. try { IntPtr display = dpy.Lock(); XWindow pwindow = parent.GetWidgetHandle(); XWindow window = Xlib.XCreateWindow (display, pwindow, x, y, (uint)width, (uint)height, (uint)0, 0 /* depth */, 2 /* InputOnly */, screen.DefaultVisual, (uint)0, IntPtr.Zero); SetWidgetHandle(window); if(parent.AutoMapChildren) { Xlib.XMapWindow(display, window); mapped = true; } } finally { dpy.Unlock(); } // Push the widget down to the default layer. layer = 0x7FFFFFFF; Layer = 0; ok = true; // Select for mouse events. SelectInput(EventMask.ButtonPressMask | EventMask.ButtonReleaseMask | EventMask.EnterWindowMask | EventMask.LeaveWindowMask | EventMask.PointerMotionMask); } finally { if(!ok) { // Creation failed, so detach ourselves from // the parent's widget tree. Detach(false); } } }
// Internal constructor that is used by the "InputOutputWidget" subclass. internal InputOnlyWidget(Widget parent, int x, int y, int width, int height, Color background, bool rootAllowed, bool overrideRedirect) : base(GetDisplay(parent, rootAllowed), GetScreen(parent), DrawableKind.Widget, parent) { bool ok = false; try { // Validate the position and size. if(x < -32768 || x > 32767 || y < -32768 || y > 32767) { throw new XException(S._("X_InvalidPosition")); } if(width < 1 || width > 32767 || height < 1 || height > 32767 || !ValidateSize(width, height)) { throw new XException(S._("X_InvalidSize")); } // Set the initial position and size of the widget. this.x = x; this.y = y; this.width = width; this.height = height; this.focusable = true; // Lock down the display and create the window handle. try { IntPtr display = dpy.Lock(); XWindow pwindow = parent.GetWidgetHandle(); XSetWindowAttributes attrs = new XSetWindowAttributes(); attrs.override_redirect = overrideRedirect; XWindow window = Xlib.XCreateWindow (display, pwindow, x, y, (uint)width, (uint)height, (uint)0, screen.DefaultDepth, 1 /* InputOutput */, screen.DefaultVisual, (uint)(CreateWindowMask.CWOverrideRedirect), ref attrs); SetWidgetHandle(window); if(background.Index == StandardColor.Inherit) { Xlib.XSetWindowBackgroundPixmap (display, window, XPixmap.ParentRelative); } else { Xlib.XSetWindowBackground(display, window, ToPixel(background)); } if(parent.AutoMapChildren) { Xlib.XMapWindow(display, window); mapped = true; } } finally { dpy.Unlock(); } // Push the widget down to the default layer. layer = 0x7FFFFFFF; Layer = 0; ok = true; // Select for mouse events. SelectInput(EventMask.ButtonPressMask | EventMask.ButtonReleaseMask | EventMask.EnterWindowMask | EventMask.LeaveWindowMask | EventMask.PointerMotionMask); } finally { if(!ok) { // Creation failed, so detach ourselves from // the parent's widget tree. Detach(false); } } }
// Reposition this widget above one of its siblings. private void RepositionAbove(Widget child) { // Detach ourselves from the widget tree. if(nextAbove != null) { nextAbove.nextBelow = nextBelow; } else { parent.topChild = nextBelow; } if(nextBelow != null) { nextBelow.nextAbove = nextAbove; } // Re-insert at the new position. nextAbove = child.nextAbove; nextBelow = child; if(nextAbove != null) { nextAbove.nextBelow = this; } else { parent.topChild = this; } child.nextAbove = this; try { IntPtr display = dpy.Lock(); XWindowChanges changes = new XWindowChanges(); changes.stack_mode = 0; /* Above */ if(child is TopLevelWindow) { Xlib.XConfigureWindow (display, GetWidgetHandle(), (uint)(ConfigureWindowMask.CWStackMode), ref changes); } else { changes.sibling = child.GetWidgetHandle(); Xlib.XConfigureWindow (display, GetWidgetHandle(), (uint)(ConfigureWindowMask.CWSibling | ConfigureWindowMask.CWStackMode), ref changes); } } finally { dpy.Unlock(); } }
// Set this cursor on a widget. internal void SetCursor(Widget widget) { Display dpy = widget.dpy; try { IntPtr display = dpy.Lock(); XWindow window = widget.GetWidgetHandle(); if(source != null) { if(cursor == XCursor.Zero) { XColor foreground = new XColor(); foreground.red = (ushort)0; foreground.green = (ushort)0; foreground.blue = (ushort)0; foreground.flags = (XColor.DoRed | XColor.DoGreen | XColor.DoBlue); XColor background = new XColor(); background.red = (ushort)0xFFFF; background.green = (ushort)0xFFFF; background.blue = (ushort)0xFFFF; background.flags = (XColor.DoRed | XColor.DoGreen | XColor.DoBlue); if(reverse) { cursor = Xlib.XCreatePixmapCursor (display, source.GetPixmapHandle(), mask.GetPixmapHandle(), ref background, ref foreground, (uint)hotspotX, (uint)hotspotY); } else { cursor = Xlib.XCreatePixmapCursor (display, source.GetPixmapHandle(), mask.GetPixmapHandle(), ref foreground, ref background, (uint)hotspotX, (uint)hotspotY); } } Xlib.XDefineCursor(display, window, cursor); } else if(type == CursorType.XC_inherit_parent) { Xlib.XUndefineCursor(display, window); } else { Xlib.XDefineCursor (display, window, dpy.GetCursor(type)); } } finally { dpy.Unlock(); } }
/// <summary> /// <para>Reparent this widget underneath a new parent.</para> /// </summary> /// /// <param name="newParent"> /// <para>The new parent widget. This should be the placeholder widget /// for the screen if you wish to give this widget "no parent".</para> /// </param> /// /// <param name="x"> /// <para>The X co-ordinate of the new top-left widget corner.</para> /// </param> /// /// <param name="y"> /// <para>The Y co-ordinate of the new top-left widget corner.</para> /// </param> /// /// <exception cref="T:System.ArgumentNullException"> /// <para>Raised if <paramref name="newParent"/> is /// <see langword="null"/>.</para> /// </exception> /// /// <exception cref="T:Xsharp.XException"> /// <para>Raised if <paramref name="x"/> or <paramref name="y"/> /// is out of range.</para> /// </exception> /// /// <exception cref="T:Xsharp.XInvalidOperationException"> /// <para>Raised if <paramref name="newParent"/> is a descendent /// of this widget, which would create a circularity.</para> /// </exception> /// /// <exception cref="T:Xsharp.XInvalidOperationException"> /// <para>Raised if <paramref name="newParent"/> is on a different /// screen from this widget.</para> /// </exception> /// /// <exception cref="T:Xsharp.XInvalidOperationException"> /// <para>Raised if <paramref name="newParent"/> is an input only /// widget, but this widget is input-output.</para> /// </exception> /// /// <exception cref="T:Xsharp.XInvalidOperationException"> /// <para>Raised if an attempt is made to reparent the root window /// or a top-level window.</para> /// </exception> public virtual void Reparent(Widget newParent, int x, int y) { // Validate the parameters. if(newParent == null) { throw new ArgumentNullException("newParent"); } if(x < -32768 || x > 32767 || y < -32768 || y > 32767) { throw new XException(S._("X_InvalidPosition")); } Widget temp = newParent; while(temp != null && temp != this) { temp = temp.parent; } if(temp != null) { throw new XInvalidOperationException (S._("X_InvalidReparent")); } if(screen != newParent.screen) { throw new XInvalidOperationException (S._("X_InvalidReparent")); } if(!(newParent is InputOutputWidget) && this is InputOutputWidget) { throw new XInvalidOperationException (S._("X_InvalidReparent")); } // If the new parent is the same as the old, then simply // move and raise the widget, but do nothing else. if(newParent == parent) { Move(x, y); Raise(); return; } // Detach the widget from its current parent. if(nextBelow != null) { nextBelow.nextAbove = nextAbove; } if(nextAbove != null) { nextAbove.nextBelow = nextBelow; } else if(parent != null) { parent.topChild = nextBelow; } // Attach the widget to its new parent as the top-most child. nextBelow = newParent.topChild; nextAbove = null; if(newParent.topChild != null) { newParent.topChild.nextAbove = this; } newParent.topChild = this; parent = newParent; // Temporarily put the widget in the top-most layer. int saveLayer = layer; layer = 0x7FFFFFFF; // Perform the actual reparent operation. This will // put the window at the top of the stacking order. try { IntPtr display = dpy.Lock(); XWindow widget = GetWidgetHandle(); XWindow pwidget = newParent.GetWidgetHandle(); Xlib.XReparentWindow(display, widget, pwidget, x, y); this.x = x; this.y = y; } finally { dpy.Unlock(); } // Push the widget down to its original layer position. Layer = saveLayer; }