internal override IntPtr CreateWindow (CreateParams cp)
{
XSetWindowAttributes Attributes;
Hwnd hwnd;
Hwnd parent_hwnd = null;
int X;
int Y;
int Width;
int Height;
IntPtr ParentHandle;
IntPtr WholeWindow;
IntPtr ClientWindow;
SetWindowValuemask ValueMask;
int[] atoms;
hwnd = new Hwnd();
Attributes = new XSetWindowAttributes();
X = cp.X;
Y = cp.Y;
Width = cp.Width;
Height = cp.Height;
if (Width<1) Width=1;
if (Height<1) Height=1;
if (cp.Parent != IntPtr.Zero) {
parent_hwnd = Hwnd.ObjectFromHandle(cp.Parent);
ParentHandle = parent_hwnd.client_window;
} else {
if (StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
// We need to use our foster parent window until this poor child gets it's parent assigned
ParentHandle=FosterParent;
} else {
ParentHandle=RootWindow;
}
}
// Set the default location location for forms.
Point next;
if (cp.control is Form) {
next = Hwnd.GetNextStackedFormLocation (cp, parent_hwnd);
X = next.X;
Y = next.Y;
}
ValueMask = SetWindowValuemask.BitGravity | SetWindowValuemask.WinGravity;
Attributes.bit_gravity = Gravity.NorthWestGravity;
Attributes.win_gravity = Gravity.NorthWestGravity;
// Save what's under the toolwindow
if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
Attributes.save_under = true;
ValueMask |= SetWindowValuemask.SaveUnder;
}
// If we're a popup without caption we override the WM
if (StyleSet (cp.Style, WindowStyles.WS_POPUP) && !StyleSet (cp.Style, WindowStyles.WS_CAPTION)) {
Attributes.override_redirect = true;
ValueMask |= SetWindowValuemask.OverrideRedirect;
}
hwnd.x = X;
hwnd.y = Y;
hwnd.width = Width;
hwnd.height = Height;
hwnd.parent = Hwnd.ObjectFromHandle(cp.Parent);
hwnd.initial_style = cp.WindowStyle;
hwnd.initial_ex_style = cp.WindowExStyle;
if (StyleSet (cp.Style, WindowStyles.WS_DISABLED)) {
hwnd.enabled = false;
}
ClientWindow = IntPtr.Zero;
Size XWindowSize = TranslateWindowSizeToXWindowSize (cp);
Rectangle XClientRect = TranslateClientRectangleToXClientRectangle (hwnd, cp.control);
lock (XlibLock) {
WholeWindow = XCreateWindow(DisplayHandle, ParentHandle, X, Y, XWindowSize.Width, XWindowSize.Height, 0, (int)CreateWindowArgs.CopyFromParent, (int)CreateWindowArgs.InputOutput, IntPtr.Zero, new UIntPtr ((uint)ValueMask), ref Attributes);
if (WholeWindow != IntPtr.Zero) {
ValueMask &= ~(SetWindowValuemask.OverrideRedirect | SetWindowValuemask.SaveUnder);
if (CustomVisual != IntPtr.Zero && CustomColormap != IntPtr.Zero) {
ValueMask = SetWindowValuemask.ColorMap;
Attributes.colormap = CustomColormap;
}
ClientWindow = XCreateWindow(DisplayHandle, WholeWindow, XClientRect.X, XClientRect.Y, XClientRect.Width, XClientRect.Height, 0, (int)CreateWindowArgs.CopyFromParent, (int)CreateWindowArgs.InputOutput, CustomVisual, new UIntPtr ((uint)ValueMask), ref Attributes);
}
}
if ((WholeWindow == IntPtr.Zero) || (ClientWindow == IntPtr.Zero)) {
throw new Exception("Could not create X11 windows");
}
hwnd.Queue = ThreadQueue(Thread.CurrentThread);
hwnd.WholeWindow = WholeWindow;
hwnd.ClientWindow = ClientWindow;
#if DriverDebug || DriverDebugCreate
Console.WriteLine("Created window {0:X} / {1:X} parent {2:X}, Style {3}, ExStyle {4}", ClientWindow.ToInt32(), WholeWindow.ToInt32(), hwnd.parent != null ? hwnd.parent.Handle.ToInt32() : 0, (WindowStyles)cp.Style, (WindowExStyles)cp.ExStyle);
#endif
if (!StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
if ((X != unchecked((int)0x80000000)) && (Y != unchecked((int)0x80000000))) {
XSizeHints hints;
hints = new XSizeHints();
hints.x = X;
hints.y = Y;
hints.flags = (IntPtr)(XSizeHintsFlags.USPosition | XSizeHintsFlags.PPosition);
XSetWMNormalHints(DisplayHandle, WholeWindow, ref hints);
}
}
lock (XlibLock) {
XSelectInput(DisplayHandle, hwnd.whole_window, new IntPtr ((int)(SelectInputMask | EventMask.StructureNotifyMask | EventMask.PropertyChangeMask | Keyboard.KeyEventMask)));
if (hwnd.whole_window != hwnd.client_window)
XSelectInput(DisplayHandle, hwnd.client_window, new IntPtr ((int)(SelectInputMask | EventMask.StructureNotifyMask | Keyboard.KeyEventMask)));
}
if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOPMOST)) {
atoms = new int[2];
atoms[0] = _NET_WM_WINDOW_TYPE_NORMAL.ToInt32();
XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_WINDOW_TYPE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
XSetTransientForHint (DisplayHandle, hwnd.whole_window, RootWindow);
}
SetWMStyles(hwnd, cp);
// set the group leader
XWMHints wm_hints = new XWMHints ();
wm_hints.flags = (IntPtr)(XWMHintsFlags.InputHint | XWMHintsFlags.StateHint | XWMHintsFlags.WindowGroupHint);
wm_hints.input = !StyleSet (cp.Style, WindowStyles.WS_DISABLED);
wm_hints.initial_state = StyleSet (cp.Style, WindowStyles.WS_MINIMIZE) ? XInitialState.IconicState : XInitialState.NormalState;
if (ParentHandle != RootWindow) {
wm_hints.window_group = hwnd.whole_window;
} else {
wm_hints.window_group = ParentHandle;
}
lock (XlibLock) {
XSetWMHints(DisplayHandle, hwnd.whole_window, ref wm_hints );
}
if (StyleSet (cp.Style, WindowStyles.WS_MINIMIZE)) {
SetWindowState(hwnd.Handle, FormWindowState.Minimized);
} else if (StyleSet (cp.Style, WindowStyles.WS_MAXIMIZE)) {
SetWindowState(hwnd.Handle, FormWindowState.Maximized);
}
// for now make all windows dnd enabled
Dnd.SetAllowDrop (hwnd, true);
// Set caption/window title
Text(hwnd.Handle, cp.Caption);
SendMessage (hwnd.Handle, Msg.WM_CREATE, (IntPtr)1, IntPtr.Zero /* XXX unused */);
SendParentNotify (hwnd.Handle, Msg.WM_CREATE, int.MaxValue, int.MaxValue);
if (StyleSet (cp.Style, WindowStyles.WS_VISIBLE)) {
hwnd.visible = true;
MapWindow(hwnd, WindowType.Both);
if (!(Control.FromHandle(hwnd.Handle) is Form))
SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, (IntPtr)1, IntPtr.Zero);
}
return hwnd.Handle;
}