// Extra detailed debug
#undef DriverDebugExtra
+#undef DriverDebugParent
+#undef DriverDebugCreate
+#undef DriverDebugDestroy
using System;
using System.ComponentModel;
using System.Drawing.Imaging;
using System.IO;
using System.Net;
-using N = System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.InteropServices;
private static ClipboardStruct Clipboard; // Our clipboard
// Communication
- private static int PostAtom; // PostMessage atom
- private static int AsyncAtom; // Support for async messages
+ private static IntPtr PostAtom; // PostMessage atom
+ private static IntPtr AsyncAtom; // Support for async messages
// Message Loop
- private static XEventQueue MessageQueue; // Holds our queued up events
+ private static Hashtable MessageQueues; // Holds our thread-specific XEventQueues
#if __MonoCS__ //
private static Pollfd[] pollfds; // For watching the X11 socket
#endif //
private static CaretStruct Caret; //
// Support for Window Styles
- private static int[] NetAtoms; // All atoms we know
+ private static IntPtr[] NetAtoms; // All atoms we know
// mouse hover message generation
private static HoverStruct HoverState; //
// Now regular initialization
XlibLock = new object ();
- MessageQueue = new XEventQueue ();
+ MessageQueues = new Hashtable(7);
TimerList = new ArrayList ();
XInitThreads();
StringBuilder sb;
string x_error_text;
string error;
+ string hwnd_text;
+ string control_text;
+ Hwnd hwnd;
+ Control c;
sb = new StringBuilder(160);
XGetErrorText(Display, ErrorCode, sb, sb.Capacity);
x_error_text = sb.ToString();
+ hwnd = Hwnd.ObjectFromHandle(ResourceID);
+ if (hwnd != null) {
+ hwnd_text = hwnd.ToString();
+ c = Control.FromHandle(hwnd.Handle);
+ if (c != null) {
+ control_text = c.ToString();
+ } else {
+ control_text = String.Format("<handle {0:X} non-existant>", hwnd.Handle);
+ }
+ } else {
+ hwnd_text = "<null>";
+ control_text = "<null>";
+ }
- error = String.Format("\n Error: {0}\n Request: {1:D} ({2})\n Resource ID: 0x{3:x}\n Serial: {4}", x_error_text, RequestCode, RequestCode, ResourceID.ToInt32(), Serial);
+
+ error = String.Format("\n Error: {0}\n Request: {1:D} ({2})\n Resource ID: 0x{3:X}\n Serial: {4}\n Hwnd: {5}\n Control: {6}", x_error_text, RequestCode, RequestCode, ResourceID.ToInt32(), Serial, hwnd_text, control_text);
return error;
}
}
}
// Generic X11 setup
- ScreenNo = 0;
+ ScreenNo = XDefaultScreen(DisplayHandle);
RootWindow = XRootWindow(DisplayHandle, ScreenNo);
DefaultColormap = XDefaultColormap(DisplayHandle, ScreenNo);
// Create the foster parent
- FosterParent=XCreateSimpleWindow(DisplayHandle, RootWindow, 0, 0, 1, 1, 4, 0, 0);
+ FosterParent=XCreateSimpleWindow(DisplayHandle, RootWindow, 0, 0, 1, 1, 4, UIntPtr.Zero, UIntPtr.Zero);
if (FosterParent==IntPtr.Zero) {
Console.WriteLine("XplatUIX11 Constructor failed to create FosterParent");
}
hwnd = new Hwnd();
+ hwnd.Queue = ThreadQueue(Thread.CurrentThread);
hwnd.WholeWindow = FosterParent;
hwnd.ClientWindow = FosterParent;
+ // Create a HWND for RootWIndow as well, so our queue doesn't eat the events
+ hwnd = new Hwnd();
+ hwnd.Queue = ThreadQueue(Thread.CurrentThread);
+ hwnd.whole_window = RootWindow;
+ hwnd.ClientWindow = RootWindow;
+
// For sleeping on the X11 socket
listen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
IPEndPoint ep = new IPEndPoint(IPAddress.Loopback, 0);
pollfds [1].events = PollEvents.POLLIN;
#endif
- Keyboard = new X11Keyboard(DisplayHandle);
+ Keyboard = new X11Keyboard(DisplayHandle, FosterParent);
Dnd = new X11Dnd (DisplayHandle);
PostQuitState = false;
HoverState.Timer = new Timer();
HoverState.Timer.Enabled = false;
HoverState.Timer.Interval = HoverState.Interval;
- HoverState.Timer.Tick +=new EventHandler(MouseHover);
+ HoverState.Timer.Tick += new EventHandler(MouseHover);
+ HoverState.Size = new Size(4, 4);
HoverState.X = -1;
HoverState.Y = -1;
SetupAtoms();
// Grab atom changes off the root window to catch certain WM events
- XSelectInput(DisplayHandle, RootWindow, EventMask.PropertyChangeMask);
+ XSelectInput(DisplayHandle, RootWindow, new IntPtr ((int)EventMask.PropertyChangeMask));
// Handle any upcoming errors
ErrorHandler = new XErrorHandler(HandleError);
#region Private Methods
private static void SetupAtoms() {
- NetAtoms = new int[(int)NA.LAST_NET_ATOM];
+ NetAtoms = new IntPtr[(int)NA.LAST_NET_ATOM];
NetAtoms[(int)NA.WM_PROTOCOLS] = XInternAtom(DisplayHandle, "WM_PROTOCOLS", false);
NetAtoms[(int)NA.WM_DELETE_WINDOW] = XInternAtom(DisplayHandle, "WM_DELETE_WINDOW", false);
NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_HORZ] = XInternAtom(DisplayHandle, "_NET_WM_STATE_MAXIMIZED_HORZ", false);
NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_VERT] = XInternAtom(DisplayHandle, "_NET_WM_STATE_MAXIMIZED_VERT", false);
+ NetAtoms[(int)NA._NET_WM_STATE_HIDDEN] = XInternAtom(DisplayHandle, "_NET_WM_STATE_HIDDEN", false);
NetAtoms[(int)NA._XEMBED] = XInternAtom(DisplayHandle, "_XEMBED", false);
NetAtoms[(int)NA._XEMBED_INFO] = XInternAtom(DisplayHandle, "_XEMBED_INFO", false);
NetAtoms[(int)NA._NET_WM_STATE_ABOVE] = XInternAtom(DisplayHandle, "_NET_WM_STATE_ABOVE", false);
NetAtoms[(int)NA._NET_WM_STATE_MODAL] = XInternAtom(DisplayHandle, "_NET_WM_STATE_MODAL", false);
NetAtoms[(int)NA._NET_WM_CONTEXT_HELP] = XInternAtom(DisplayHandle, "_NET_WM_CONTEXT_HELP", false);
+ NetAtoms[(int)NA._NET_WM_WINDOW_OPACITY] = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_OPACITY", false);
+
+ NetAtoms[(int)NA._NET_WM_WINDOW_TYPE_DESKTOP] = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE_DESKTOP", false);
+ NetAtoms[(int)NA._NET_WM_WINDOW_TYPE_DOCK] = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE_DOCK", false);
+ NetAtoms[(int)NA._NET_WM_WINDOW_TYPE_TOOLBAR] = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE_TOOLBAR", false);
+ NetAtoms[(int)NA._NET_WM_WINDOW_TYPE_MENU] = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE_MENU", false);
+ NetAtoms[(int)NA._NET_WM_WINDOW_TYPE_UTILITY] = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE_UTILITY", false);
+ NetAtoms[(int)NA._NET_WM_WINDOW_TYPE_DIALOG] = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE_DIALOG", false);
+ NetAtoms[(int)NA._NET_WM_WINDOW_TYPE_SPLASH] = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE_SPLASH", false);
+ NetAtoms[(int)NA._NET_WM_WINDOW_TYPE_NORMAL] = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE_NORMAL", false);
// Clipboard support
NetAtoms[(int)NA.CLIPBOARD] = XInternAtom (DisplayHandle, "CLIPBOARD", false);
- NetAtoms[(int)NA.DIB] = (int)Atom.XA_PIXMAP;
+ NetAtoms[(int)NA.DIB] = (IntPtr)Atom.XA_PIXMAP;
NetAtoms[(int)NA.OEMTEXT] = XInternAtom(DisplayHandle, "COMPOUND_TEXT", false);
NetAtoms[(int)NA.UNICODETEXT] = XInternAtom(DisplayHandle, "UTF8_STRING", false);
NetAtoms[(int)NA.TARGETS] = XInternAtom(DisplayHandle, "TARGETS", false);
xev.ClientMessageEvent.ptr1 = l0;
xev.ClientMessageEvent.ptr2 = l1;
xev.ClientMessageEvent.ptr3 = l2;
- XSendEvent(DisplayHandle, RootWindow, false, EventMask.SubstructureRedirectMask | EventMask.SubstructureNotifyMask, ref xev);
+ XSendEvent(DisplayHandle, RootWindow, false, new IntPtr ((int) (EventMask.SubstructureRedirectMask | EventMask.SubstructureNotifyMask)), ref xev);
}
private void SendNetClientMessage(IntPtr window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2) {
xev.ClientMessageEvent.ptr1 = l0;
xev.ClientMessageEvent.ptr2 = l1;
xev.ClientMessageEvent.ptr3 = l2;
- XSendEvent(DisplayHandle, window, false, EventMask.NoEventMask, ref xev);
+ XSendEvent(DisplayHandle, window, false, new IntPtr ((int)EventMask.NoEventMask), ref xev);
}
- private void DeriveStyles(IntPtr handle, int Style, int ExStyle, out FormBorderStyle border_style, out TitleStyle title_style, out int caption_height, out int tool_caption_height) {
+ private void DeriveStyles(int Style, int ExStyle, out FormBorderStyle border_style, out TitleStyle title_style, out int caption_height, out int tool_caption_height) {
// Only MDI windows get caption_heights
caption_height = 0;
tool_caption_height = 19;
- if ((Style & (int) WindowStyles.WS_OVERLAPPEDWINDOW) == 0) {
- if ((Style & (int) WindowStyles.WS_BORDER) != 0) {
- border_style = FormBorderStyle.FixedSingle;
- } else if ((ExStyle & (int) WindowStyles.WS_EX_CLIENTEDGE) != 0) {
+ if ((Style & (int) WindowStyles.WS_CHILD) != 0) {
+ if ((ExStyle & (int) WindowExStyles.WS_EX_CLIENTEDGE) != 0) {
border_style = FormBorderStyle.Fixed3D;
- } else {
+ } else if ((Style & (int) WindowStyles.WS_BORDER) == 0) {
border_style = FormBorderStyle.None;
+ } else {
+ border_style = FormBorderStyle.FixedSingle;
}
title_style = TitleStyle.None;
- } else {
- bool is_mdi = false;
- if ((ExStyle & (int) WindowStyles.WS_EX_MDICHILD) != 0) {
+ if ((ExStyle & (int) WindowExStyles.WS_EX_MDICHILD) != 0) {
caption_height = 26;
- is_mdi = true;
+
+ if ((Style & (int)WindowStyles.WS_CAPTION) != 0) {
+ if ((ExStyle & (int)WindowExStyles.WS_EX_TOOLWINDOW) != 0) {
+ title_style = TitleStyle.Tool;
+ } else {
+ title_style = TitleStyle.Normal;
+ }
+ }
+
+ if ((Style & (int) WindowStyles.WS_OVERLAPPEDWINDOW) != 0 ||
+ (ExStyle & (int) WindowExStyles.WS_EX_TOOLWINDOW) != 0) {
+ border_style = (FormBorderStyle) 0xFFFF;
+ } else {
+ border_style = FormBorderStyle.None;
+ }
}
+ } else {
title_style = TitleStyle.None;
if ((Style & (int)WindowStyles.WS_CAPTION) != 0) {
- if ((ExStyle & (int)WindowStyles.WS_EX_TOOLWINDOW) != 0) {
+ if ((ExStyle & (int)WindowExStyles.WS_EX_TOOLWINDOW) != 0) {
title_style = TitleStyle.Tool;
} else {
title_style = TitleStyle.Normal;
}
}
- if (!is_mdi) {
- border_style = FormBorderStyle.None;
- if ((ExStyle & (int)WindowStyles.WS_EX_WINDOWEDGE) != 0) {
- if ((ExStyle & (int)WindowStyles.WS_EX_TOOLWINDOW) != 0) {
- if ((Style & (int)WindowStyles.WS_THICKFRAME) != 0) {
- border_style = FormBorderStyle.SizableToolWindow;
- } else {
- border_style = FormBorderStyle.FixedToolWindow;
- }
- } else if ((ExStyle & (int)WindowStyles.WS_EX_DLGMODALFRAME) != 0) {
+ border_style = FormBorderStyle.None;
+
+ if ((Style & (int)WindowStyles.WS_THICKFRAME) != 0) {
+ if ((ExStyle & (int)WindowExStyles.WS_EX_TOOLWINDOW) != 0) {
+ border_style = FormBorderStyle.SizableToolWindow;
+ } else {
+ border_style = FormBorderStyle.Sizable;
+ }
+ } else {
+ if ((Style & (int)WindowStyles.WS_CAPTION) == (int)WindowStyles.WS_CAPTION) {
+ if ((ExStyle & (int)WindowExStyles.WS_EX_CLIENTEDGE) != 0) {
+ border_style = FormBorderStyle.Fixed3D;
+ } else if ((ExStyle & (int)WindowExStyles.WS_EX_DLGMODALFRAME) != 0) {
border_style = FormBorderStyle.FixedDialog;
- } else if ((ExStyle & (int)WindowStyles.WS_THICKFRAME) != 0) {
- border_style = FormBorderStyle.Sizable;
- } else {
+ } else if ((ExStyle & (int)WindowExStyles.WS_EX_TOOLWINDOW) != 0) {
+ border_style = FormBorderStyle.FixedToolWindow;
+ } else if ((Style & (int)WindowStyles.WS_BORDER) != 0) {
border_style = FormBorderStyle.FixedSingle;
}
} else {
- border_style = FormBorderStyle.Fixed3D;
+ if ((Style & (int)WindowStyles.WS_BORDER) != 0) {
+ border_style = FormBorderStyle.FixedSingle;
+ }
}
- } else {
- if ((Style & (int) WindowStyles.WS_OVERLAPPEDWINDOW) != 0 ||
- (ExStyle & (int) WindowStyles.WS_EX_TOOLWINDOW) != 0)
- border_style = (FormBorderStyle) 0xFFFF;
- else
- border_style = FormBorderStyle.None;
}
}
}
private void SetHwndStyles(Hwnd hwnd, CreateParams cp) {
- DeriveStyles(hwnd.Handle, cp.Style, cp.ExStyle, out hwnd.border_style, out hwnd.title_style, out hwnd.caption_height, out hwnd.tool_caption_height);
+ DeriveStyles(cp.Style, cp.ExStyle, out hwnd.border_style, out hwnd.title_style, out hwnd.caption_height, out hwnd.tool_caption_height);
}
private void SetWMStyles(Hwnd hwnd, CreateParams cp) {
MotifWmHints mwmHints;
MotifFunctions functions;
MotifDecorations decorations;
- uint[] atoms;
int atom_count;
Rectangle client_rect;
+ bool transient;
+
+ // Child windows don't need WM window styles
+ if ((cp.Style & (int)WindowStyles.WS_CHILDWINDOW) != 0) {
+ return;
+ }
+
+ transient = false;
mwmHints = new MotifWmHints();
functions = 0;
functions |= MotifFunctions.Move | MotifFunctions.Resize;
decorations |= MotifDecorations.Border | MotifDecorations.ResizeH;
}
-
if ((cp.Style & ((int)WindowStyles.WS_MINIMIZEBOX)) != 0) {
functions |= MotifFunctions.Minimize;
decorations |= MotifDecorations.Minimize;
functions |= MotifFunctions.Close;
}
- if ((cp.ExStyle & ((int)WindowStyles.WS_EX_DLGMODALFRAME)) != 0) {
+ if ((cp.ExStyle & ((int)WindowExStyles.WS_EX_DLGMODALFRAME)) != 0) {
decorations |= MotifDecorations.Border;
}
decorations |= MotifDecorations.Border;
}
- if ((cp.ExStyle & ((int)WindowStyles.WS_EX_TOOLWINDOW)) != 0) {
+ if ((cp.ExStyle & ((int)WindowExStyles.WS_EX_TOOLWINDOW)) != 0) {
functions = 0;
decorations = 0;
}
+ if ((functions & MotifFunctions.Resize) == 0) {
+ hwnd.fixed_size = true;
+ XplatUI.SetWindowMinMax(hwnd.Handle, new Rectangle(cp.X, cp.Y, cp.Width, cp.Height), new Size(cp.Width, cp.Height), new Size(cp.Width, cp.Height));
+ } else {
+ hwnd.fixed_size = false;
+ }
+
mwmHints.functions = (IntPtr)functions;
mwmHints.decorations = (IntPtr)decorations;
XChangeProperty(DisplayHandle, hwnd.whole_window, NetAtoms[(int)NA._MOTIF_WM_HINTS], NetAtoms[(int)NA._MOTIF_WM_HINTS], 32, PropertyMode.Replace, ref mwmHints, 5);
if (((cp.Style & (int)WindowStyles.WS_POPUP) != 0) && (hwnd.parent != null) && (hwnd.parent.whole_window != IntPtr.Zero)) {
+ transient = true;
XSetTransientForHint(DisplayHandle, hwnd.whole_window, hwnd.parent.whole_window);
+ } else if ((cp.ExStyle & (int)WindowExStyles.WS_EX_APPWINDOW) == 0) {
+ transient = true;
+ XSetTransientForHint(DisplayHandle, hwnd.whole_window, FosterParent);
+ }
+ if ((client_rect.Width < 1) || (client_rect.Height < 1)) {
+ XMoveResizeWindow(DisplayHandle, hwnd.client_window, -5, -5, 1, 1);
+ } else {
+ XMoveResizeWindow(DisplayHandle, hwnd.client_window, client_rect.X, client_rect.Y, client_rect.Width, client_rect.Height);
}
- XMoveResizeWindow(DisplayHandle, hwnd.client_window, client_rect.X, client_rect.Y, client_rect.Width, client_rect.Height);
- atoms = new uint[8];
+ int[] atoms = new int[8];
atom_count = 0;
- if ((cp.ExStyle & ((int)WindowStyles.WS_EX_TOOLWINDOW)) != 0) {
- atoms[atom_count++] = (uint)NetAtoms[(int)NA._NET_WM_STATE_NO_TASKBAR];
+ if ((cp.ExStyle & ((int)WindowExStyles.WS_EX_TOOLWINDOW)) != 0) {
+ atoms[atom_count++] = NetAtoms[(int)NA._NET_WM_STATE_NO_TASKBAR].ToInt32();
}
+ XChangeProperty(DisplayHandle, hwnd.whole_window, NetAtoms[(int)NA._NET_WM_STATE], (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, atom_count);
- XChangeProperty(DisplayHandle, hwnd.whole_window, NetAtoms[(int)NA._NET_WM_STATE], Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, atom_count);
+ if ((cp.ExStyle & (int)WindowExStyles.WS_EX_TOPMOST) != 0) {
+ atom_count = 0;
+ atoms[atom_count++] = atoms[atom_count++] = NetAtoms[(int)NA._NET_WM_WINDOW_TYPE_DOCK].ToInt32();
+ XChangeProperty(DisplayHandle, hwnd.whole_window, NetAtoms[(int)NA._NET_WM_WINDOW_TYPE], (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, atom_count);
+ } else if (transient) {
+ atom_count = 0;
+
+ if ((cp.ExStyle & ((int)WindowExStyles.WS_EX_TOOLWINDOW)) != 0) {
+ atoms[atom_count++] = atoms[atom_count++] = NetAtoms[(int)NA._NET_WM_WINDOW_TYPE_DOCK].ToInt32();
+ } else {
+ atoms[atom_count++] = atoms[atom_count++] = NetAtoms[(int)NA._NET_WM_WINDOW_TYPE_DIALOG].ToInt32();
+ }
+ XChangeProperty(DisplayHandle, hwnd.whole_window, NetAtoms[(int)NA._NET_WM_WINDOW_TYPE], (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, atom_count);
+ }
atom_count = 0;
- atoms[atom_count++] = (uint)NetAtoms[(int)NA.WM_DELETE_WINDOW];
- if ((cp.ExStyle & (int)WindowStyles.WS_EX_CONTEXTHELP) != 0) {
- atoms[atom_count++] = (uint)NetAtoms[(int)NA._NET_WM_CONTEXT_HELP];
+ IntPtr[] atom_ptrs = new IntPtr[2];
+
+ atom_ptrs[atom_count++] = NetAtoms[(int)NA.WM_DELETE_WINDOW];
+ if ((cp.ExStyle & (int)WindowExStyles.WS_EX_CONTEXTHELP) != 0) {
+ atom_ptrs[atom_count++] = NetAtoms[(int)NA._NET_WM_CONTEXT_HELP];
}
- XSetWMProtocols(DisplayHandle, hwnd.whole_window, atoms, atom_count);
+ XSetWMProtocols(DisplayHandle, hwnd.whole_window, atom_ptrs, atom_count);
}
}
private void SetIcon(Hwnd hwnd, Icon icon) {
Bitmap bitmap;
int size;
- uint[] data;
+ IntPtr[] data;
int index;
bitmap = icon.ToBitmap();
index = 0;
size = bitmap.Width * bitmap.Height + 2;
- data = new uint[size];
+ data = new IntPtr[size];
- data[index++] = (uint)bitmap.Width;
- data[index++] = (uint)bitmap.Height;
+ data[index++] = (IntPtr)bitmap.Width;
+ data[index++] = (IntPtr)bitmap.Height;
for (int y = 0; y < bitmap.Height; y++) {
for (int x = 0; x < bitmap.Width; x++) {
- data[index++] = (uint)bitmap.GetPixel(x, y).ToArgb();
+ data[index++] = (IntPtr)bitmap.GetPixel(x, y).ToArgb();
}
}
- XChangeProperty(DisplayHandle, hwnd.whole_window, NetAtoms[(int)NA._NET_WM_ICON], Atom.XA_CARDINAL, 32, PropertyMode.Replace, data, size);
+
+ XChangeProperty(DisplayHandle, hwnd.whole_window, NetAtoms[(int)NA._NET_WM_ICON], (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, data, size);
}
private IntPtr ImageToPixmap(Image image) {
wake.Send (new byte [] { 0xFF });
}
- private void TranslatePropertyToClipboard(int property) {
- Atom actual_atom;
+ private XEventQueue ThreadQueue(Thread thread) {
+ XEventQueue queue;
+
+ queue = (XEventQueue)MessageQueues[thread];
+ if (queue == null) {
+ queue = new XEventQueue(thread);
+ MessageQueues[thread] = queue;
+ }
+
+ return queue;
+ }
+
+ private void TranslatePropertyToClipboard(IntPtr property) {
+ IntPtr actual_atom;
int actual_format;
- int nitems;
- int bytes_after;
+ IntPtr nitems;
+ IntPtr bytes_after;
IntPtr prop = IntPtr.Zero;
Clipboard.Item = null;
- XGetWindowProperty(DisplayHandle, FosterParent, property, 0, 0x7fffffff, true, Atom.AnyPropertyType, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
+ XGetWindowProperty(DisplayHandle, FosterParent, property, IntPtr.Zero, new IntPtr (0x7fffffff), true, (IntPtr)Atom.AnyPropertyType, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
- if (nitems > 0) {
- if (property == (int)Atom.XA_STRING) {
+ if ((long)nitems > 0) {
+ if (property == (IntPtr)Atom.XA_STRING) {
Clipboard.Item = Marshal.PtrToStringAnsi(prop);
- } else if (property == (int)Atom.XA_BITMAP) {
+ } else if (property == (IntPtr)Atom.XA_BITMAP) {
// FIXME - convert bitmap to image
- } else if (property == (int)Atom.XA_PIXMAP) {
+ } else if (property == (IntPtr)Atom.XA_PIXMAP) {
// FIXME - convert pixmap to image
} else if (property == NetAtoms[(int)NA.OEMTEXT]) {
Clipboard.Item = Marshal.PtrToStringAnsi(prop);
}
}
- private void AddExpose (XEvent xevent) {
- Hwnd hwnd;
-
- hwnd = Hwnd.GetObjectFromWindow(xevent.AnyEvent.window);
-
+ private void AddExpose (Hwnd hwnd, bool client, int x, int y, int width, int height) {
// Don't waste time
- //if (hwnd == null || !hwnd.visible) { // Can'd check visible; we might loose expose for whole_windows
- if (hwnd == null) {
+ if ((hwnd == null) || (x > hwnd.Width) || (y > hwnd.Height) || ((x + width) < 0) || ((y + height) < 0)) {
return;
}
- if (xevent.AnyEvent.window == hwnd.client_window) {
- hwnd.AddInvalidArea(xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
+ // Keep the invalid area as small as needed
+ if ((x + width) > hwnd.width) {
+ width = hwnd.width - x;
+ }
+ if ((y + height) > hwnd.height) {
+ height = hwnd.height - y;
+ }
+
+ if (client) {
+ hwnd.AddInvalidArea(x, y, width, height);
if (!hwnd.expose_pending) {
- MessageQueue.Enqueue(xevent);
+ if (!hwnd.nc_expose_pending) {
+ hwnd.Queue.Paint.Enqueue(hwnd);
+ }
hwnd.expose_pending = true;
}
} else {
+ hwnd.AddNcInvalidArea (x, y, width, height);
+
if (!hwnd.nc_expose_pending) {
- MessageQueue.Enqueue(xevent);
+ if (!hwnd.expose_pending) {
+ hwnd.Queue.Paint.Enqueue(hwnd);
+ }
hwnd.nc_expose_pending = true;
}
}
private void InvalidateWholeWindow(IntPtr handle, Rectangle rectangle) {
Hwnd hwnd;
- XEvent xevent;
hwnd = Hwnd.ObjectFromHandle(handle);
-
- xevent = new XEvent ();
- xevent.type = XEventName.Expose;
- xevent.ExposeEvent.display = DisplayHandle;
- xevent.ExposeEvent.window = hwnd.whole_window;
-
- xevent.ExposeEvent.x = rectangle.X;
- xevent.ExposeEvent.y = rectangle.Y;
- xevent.ExposeEvent.width = rectangle.Width;
- xevent.ExposeEvent.height = rectangle.Height;
-
- AddExpose (xevent);
+ AddExpose (hwnd, false, rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
}
private void WholeToScreen(IntPtr handle, ref int x, ref int y) {
y = dest_y_return;
}
+ private void AbsoluteGeometry(IntPtr window, out int ret_x, out int ret_y, out int width, out int height) {
+ IntPtr root;
+ IntPtr win;
+ IntPtr parent;
+ IntPtr children;
+ int x;
+ int y;
+ int w;
+ int h;
+ int absX;
+ int absY;
+ int b;
+ int d;
+ int nchildren;
+
+ absX = 0;
+ absY = 0;
+ win = window;
+ width = 0;
+ height = 0;
+ do {
+ XGetGeometry(DisplayHandle, win, out root, out x, out y, out w, out h, out b, out d);
+ if (win == window) {
+ width = w;
+ height = h;
+ }
+ absX += x;
+ absY += y;
+ if (XQueryTree(DisplayHandle, win, out root, out parent, out children, out nchildren) == 0) {
+ break;
+ }
+
+ if (children != IntPtr.Zero) {
+ XFree(children);
+ }
+ win = parent;
+ } while (win != root);
+
+ ret_x = absX;
+ ret_y = absY;
+
+//Console.WriteLine("Absolute pos for window {0} = {1},{2} {3}x{4}", XplatUI.Window(window), ret_x, ret_y, width, height);
+ }
+
+ private void FrameExtents(IntPtr window, out int left, out int top) {
+ IntPtr actual_atom;
+ int actual_format;
+ IntPtr nitems;
+ IntPtr bytes_after;
+ IntPtr prop = IntPtr.Zero;
+
+ XGetWindowProperty(DisplayHandle, window, NetAtoms[(int)NA._NET_FRAME_EXTENTS], IntPtr.Zero, new IntPtr (16), false, (IntPtr)Atom.XA_CARDINAL, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
+ if (((long)nitems == 4) && (prop != IntPtr.Zero)) {
+ left = Marshal.ReadIntPtr(prop, 0).ToInt32();
+ //right = Marshal.ReadIntPtr(prop, IntPtr.Size).ToInt32();
+ top = Marshal.ReadIntPtr(prop, IntPtr.Size * 2).ToInt32();
+ //bottom = Marshal.ReadIntPtr(prop, IntPtr.Size * 3).ToInt32();
+ } else {
+ left = 0;
+ top = 0;
+ }
+
+ if (prop != IntPtr.Zero) {
+ XFree(prop);
+ }
+ return;
+ }
+
private void AddConfigureNotify (XEvent xevent) {
Hwnd hwnd;
return;
}
- if (xevent.ConfigureEvent.window == hwnd.whole_window) {
+ if ((xevent.ConfigureEvent.window == hwnd.whole_window) && (xevent.ConfigureEvent.window == xevent.ConfigureEvent.xevent)) {
if (!hwnd.reparented) {
hwnd.x = xevent.ConfigureEvent.x;
hwnd.y = xevent.ConfigureEvent.y;
} else {
- int dummy_int;
- IntPtr dummy_ptr;
-
- XGetGeometry(DisplayHandle, XGetParent(hwnd.whole_window), out dummy_ptr, out hwnd.x, out hwnd.y, out dummy_int, out dummy_int, out dummy_int, out dummy_int);
+ // This sucks ass, part 1
+ // Every WM does the ConfigureEvents of toplevel windows different, so there's
+ // no standard way of getting our adjustment.
+ // The code below is needed for KDE and FVWM, the 'whacky_wm' part is for metacity
+ // Several other WMs do their decorations different yet again and we fail to deal
+ // with that, since I couldn't find any frigging commonality between them.
+ // The only sane WM seems to be KDE
+
+ if (!xevent.ConfigureEvent.send_event) {
+ IntPtr dummy_ptr;
+
+ XTranslateCoordinates(DisplayHandle, hwnd.whole_window, RootWindow, -xevent.ConfigureEvent.x, -xevent.ConfigureEvent.y, out hwnd.x, out hwnd.y, out dummy_ptr);
+ } else {
+ // This is a synthetic event, coordinates are in root space
+ hwnd.x = xevent.ConfigureEvent.x;
+ hwnd.y = xevent.ConfigureEvent.y;
+ if (hwnd.whacky_wm) {
+ int frame_left;
+ int frame_top;
+
+ FrameExtents(hwnd.whole_window, out frame_left, out frame_top);
+ hwnd.x -= frame_left;
+ hwnd.y -= frame_top;
+ }
+ }
}
-
hwnd.width = xevent.ConfigureEvent.width;
hwnd.height = xevent.ConfigureEvent.height;
+ hwnd.ClientRect = Rectangle.Empty;
if (!hwnd.configure_pending) {
- MessageQueue.Enqueue(xevent);
+ hwnd.Queue.Enqueue(xevent);
hwnd.configure_pending = true;
}
}
timeout = Timer.Minimum;
}
+ if (timeout > 1000)
+ timeout = 1000;
return timeout;
}
}
}
- private void UpdateMessageQueue () {
+ private void MapWindow(Hwnd hwnd, WindowType windows) {
+ hwnd.mapped = true;
+ if ((windows & WindowType.Whole) != 0) {
+ XMapWindow(DisplayHandle, hwnd.whole_window);
+ }
+ if ((windows & WindowType.Client) != 0) {
+ XMapWindow(DisplayHandle, hwnd.client_window);
+ }
+ }
+
+ private void UnmapWindow(Hwnd hwnd, WindowType windows) {
+ hwnd.mapped = false;
+ if ((windows & WindowType.Whole) != 0) {
+ XUnmapWindow(DisplayHandle, hwnd.whole_window);
+ }
+ if ((windows & WindowType.Client) != 0) {
+ XUnmapWindow(DisplayHandle, hwnd.client_window);
+ }
+ }
+
+ private void UpdateMessageQueue (XEventQueue queue) {
DateTime now;
int pending;
+ Hwnd hwnd;
now = DateTime.Now;
if (pending == 0) {
int timeout;
+ if ((queue != null) && (queue.Paint.Count > 0)) {
+ return;
+ }
+
timeout = NextTimeout (now);
if (timeout > 0) {
#if __MonoCS__
lock (XlibLock) {
XNextEvent (DisplayHandle, ref xevent);
+
+ if (xevent.AnyEvent.type == XEventName.KeyPress) {
+ if (XFilterEvent(ref xevent, FosterParent)) {
+ continue;
+ }
+ }
}
//Console.WriteLine("Got x event {0}", xevent);
+
+ hwnd = Hwnd.GetObjectFromWindow(xevent.AnyEvent.window);
+ if (hwnd == null) {
+ if (xevent.type == XEventName.Expose) {
+ }
+ pending = XPending (DisplayHandle);
+ continue;
+ }
switch (xevent.type) {
case XEventName.Expose:
- AddExpose (xevent);
+ AddExpose (hwnd, xevent.ExposeEvent.window == hwnd.ClientWindow, xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
break;
case XEventName.SelectionClear: {
sel_event.SelectionEvent.target = xevent.SelectionRequestEvent.target;
sel_event.SelectionEvent.requestor = xevent.SelectionRequestEvent.requestor;
sel_event.SelectionEvent.time = xevent.SelectionRequestEvent.time;
- sel_event.SelectionEvent.property = 0;
+ sel_event.SelectionEvent.property = IntPtr.Zero;
// Seems that some apps support asking for supported types
if (xevent.SelectionEvent.target == NetAtoms[(int)NA.TARGETS]) {
- uint[] atoms;
+ int[] atoms;
int atom_count;
- atoms = new uint[5];
+ atoms = new int[5];
atom_count = 0;
if (Clipboard.Item is String) {
- atoms[atom_count++] = (uint)Atom.XA_STRING;
- atoms[atom_count++] = (uint)NetAtoms[(int)NA.OEMTEXT];
- atoms[atom_count++] = (uint)NetAtoms[(int)NA.UNICODETEXT];
+ atoms[atom_count++] = (int)Atom.XA_STRING;
+ atoms[atom_count++] = (int)NetAtoms[(int)NA.OEMTEXT];
+ atoms[atom_count++] = (int)NetAtoms[(int)NA.UNICODETEXT];
} else if (Clipboard.Item is Image) {
- atoms[atom_count++] = (uint)Atom.XA_PIXMAP;
- atoms[atom_count++] = (uint)Atom.XA_BITMAP;
+ atoms[atom_count++] = (int)Atom.XA_PIXMAP;
+ atoms[atom_count++] = (int)Atom.XA_BITMAP;
} else {
// FIXME - handle other types
}
- XChangeProperty(DisplayHandle, xevent.SelectionEvent.requestor, xevent.SelectionRequestEvent.property, xevent.SelectionRequestEvent.target, 32, PropertyMode.Replace, atoms, atom_count);
+ XChangeProperty(DisplayHandle, xevent.SelectionEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property, (IntPtr)xevent.SelectionRequestEvent.target, 32, PropertyMode.Replace, atoms, atom_count);
} else if (Clipboard.Item is string) {
IntPtr buffer;
int buflen;
buflen = 0;
- if (xevent.SelectionRequestEvent.target == (int)Atom.XA_STRING) {
+ if (xevent.SelectionRequestEvent.target == (IntPtr)Atom.XA_STRING) {
Byte[] bytes;
bytes = new ASCIIEncoding().GetBytes((string)Clipboard.Item);
}
if (buffer != IntPtr.Zero) {
- XChangeProperty(DisplayHandle, xevent.SelectionRequestEvent.requestor, xevent.SelectionRequestEvent.property, xevent.SelectionRequestEvent.target, 8, PropertyMode.Replace, buffer, buflen);
+ XChangeProperty(DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property, (IntPtr)xevent.SelectionRequestEvent.target, 8, PropertyMode.Replace, buffer, buflen);
sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
Marshal.FreeHGlobal(buffer);
}
} else if (Clipboard.Item is Image) {
- if (xevent.SelectionEvent.target == (int)Atom.XA_PIXMAP) {
+ if (xevent.SelectionEvent.target == (IntPtr)Atom.XA_PIXMAP) {
// FIXME - convert image and store as property
- } else if (xevent.SelectionEvent.target == (int)Atom.XA_PIXMAP) {
+ } else if (xevent.SelectionEvent.target == (IntPtr)Atom.XA_PIXMAP) {
// FIXME - convert image and store as property
}
}
- XSendEvent(DisplayHandle, xevent.SelectionRequestEvent.requestor, false, EventMask.NoEventMask, ref sel_event);
+ XSendEvent(DisplayHandle, xevent.SelectionRequestEvent.requestor, false, new IntPtr ((int)EventMask.NoEventMask), ref sel_event);
break;
}
case XEventName.SelectionNotify: {
if (Clipboard.Enumerating) {
Clipboard.Enumerating = false;
- if (xevent.SelectionEvent.property != 0) {
- XDeleteProperty(DisplayHandle, FosterParent, xevent.SelectionEvent.property);
+ if (xevent.SelectionEvent.property != IntPtr.Zero) {
+ XDeleteProperty(DisplayHandle, FosterParent, (IntPtr)xevent.SelectionEvent.property);
if (!Clipboard.Formats.Contains(xevent.SelectionEvent.property)) {
Clipboard.Formats.Add(xevent.SelectionEvent.property);
#if DriverDebugExtra
}
} else if (Clipboard.Retrieving) {
Clipboard.Retrieving = false;
- if (xevent.SelectionEvent.property != 0) {
+ if (xevent.SelectionEvent.property != IntPtr.Zero) {
TranslatePropertyToClipboard(xevent.SelectionEvent.property);
} else {
Clipboard.Item = null;
break;
}
+ case XEventName.MapNotify: {
+ if (hwnd.client_window == xevent.MapEvent.window) {
+ hwnd.mapped = true;
+ }
+ break;
+ }
+
+ case XEventName.UnmapNotify: {
+ if (hwnd.client_window == xevent.MapEvent.window) {
+ hwnd.mapped = false;
+ }
+ break;
+ }
+
case XEventName.KeyPress:
case XEventName.KeyRelease:
case XEventName.ButtonPress:
case XEventName.FocusOut:
case XEventName.ClientMessage:
case XEventName.ReparentNotify:
- MessageQueue.Enqueue (xevent);
+ hwnd.Queue.Enqueue (xevent);
break;
case XEventName.ConfigureNotify:
case XEventName.PropertyNotify:
if (xevent.PropertyEvent.atom == NetAtoms[(int)NA._NET_ACTIVE_WINDOW]) {
- Atom actual_atom;
+ IntPtr actual_atom;
int actual_format;
- int nitems;
- int bytes_after;
+ IntPtr nitems;
+ IntPtr bytes_after;
IntPtr prop = IntPtr.Zero;
IntPtr prev_active;;
prev_active = ActiveWindow;
- XGetWindowProperty(DisplayHandle, RootWindow, NetAtoms[(int)NA._NET_ACTIVE_WINDOW], 0, 1, false, Atom.XA_WINDOW, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
- if ((nitems > 0) && (prop != IntPtr.Zero)) {
+ XGetWindowProperty(DisplayHandle, RootWindow, NetAtoms[(int)NA._NET_ACTIVE_WINDOW], IntPtr.Zero, new IntPtr (1), false, (IntPtr)Atom.XA_WINDOW, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
+ if (((long)nitems > 0) && (prop != IntPtr.Zero)) {
ActiveWindow = Hwnd.GetHandleFromWindow((IntPtr)Marshal.ReadInt32(prop));
XFree(prop);
return 0;
}
- private void DestroyChildWindow(Control c) {
+ private void SendWMDestroyMessages(Control c) {
Hwnd hwnd;
int i;
Control[] controls;
if (c != null) {
controls = c.child_controls.GetAllControls ();
- for (i = 0; i < controls.Length; i++) {
- hwnd = Hwnd.ObjectFromHandle(controls[i].Handle);
+ if (c.IsHandleCreated && !c.IsDisposed) {
+ #if DriverDebugDestroy
+ Console.WriteLine("Destroying {0}, child of {1}", XplatUI.Window(c.Handle), (c.Parent != null) ? XplatUI.Window(c.Parent.Handle) : "<none>");
+ #endif
- if (hwnd != null) {
- hwnd.destroy_pending = true;
+ hwnd = Hwnd.ObjectFromHandle(c.Handle);
+ SendMessage(c.Handle, Msg.WM_DESTROY, IntPtr.Zero, IntPtr.Zero);
+ }
+
+ for (i = 0; i < controls.Length; i++) {
+ SendWMDestroyMessages(controls[i]);
+ if (controls[i].IsHandleCreated) {
+ hwnd = Hwnd.ObjectFromHandle(controls[i].Handle);
+ if (hwnd != null) {
+ hwnd.Dispose();
+ }
}
- DestroyChildWindow(controls[i]);
}
}
}
+ private void PerformNCCalc(Hwnd hwnd) {
+ XplatUIWin32.NCCALCSIZE_PARAMS ncp;
+ IntPtr ptr;
+ Rectangle rect;
+
+ rect = hwnd.DefaultClientRect;
+
+ ncp = new XplatUIWin32.NCCALCSIZE_PARAMS();
+ ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ncp));
+
+ ncp.rgrc1.left = rect.Left;
+ ncp.rgrc1.top = rect.Top;
+ ncp.rgrc1.right = rect.Right;
+ ncp.rgrc1.bottom = rect.Bottom;
+
+ Marshal.StructureToPtr(ncp, ptr, true);
+ NativeWindow.WndProc(hwnd.client_window, Msg.WM_NCCALCSIZE, (IntPtr)1, ptr);
+ ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(ptr, typeof(XplatUIWin32.NCCALCSIZE_PARAMS));
+ Marshal.FreeHGlobal(ptr);
+
+ // FIXME - debug this with Menus
+
+ rect = new Rectangle(ncp.rgrc1.left, ncp.rgrc1.top, ncp.rgrc1.right - ncp.rgrc1.left, ncp.rgrc1.bottom - ncp.rgrc1.top);
+ hwnd.ClientRect = rect;
+
+ if (hwnd.visible) {
+ if ((rect.Width < 1) || (rect.Height < 1)) {
+ XMoveResizeWindow(DisplayHandle, hwnd.client_window, -5, -5, 1, 1);
+ } else {
+ XMoveResizeWindow(DisplayHandle, hwnd.client_window, rect.X, rect.Y, rect.Width, rect.Height);
+ }
+ }
+ }
#endregion // Private Methods
#region Callbacks
private void MouseHover(object sender, EventArgs e) {
- if ((HoverState.X == MousePosition.X) && (HoverState.Y == MousePosition.Y)) {
- XEvent xevent;
+ XEvent xevent;
+ Hwnd hwnd;
- HoverState.Timer.Enabled = false;
+ HoverState.Timer.Enabled = false;
- if (HoverState.Window != IntPtr.Zero) {
+ if (HoverState.Window != IntPtr.Zero) {
+ hwnd = Hwnd.GetObjectFromWindow(HoverState.Window);
+ if (hwnd != null) {
xevent = new XEvent ();
xevent.type = XEventName.ClientMessage;
xevent.ClientMessageEvent.display = DisplayHandle;
- xevent.ClientMessageEvent.window = (IntPtr)HoverState.Window;
- xevent.ClientMessageEvent.message_type = (IntPtr)HoverState.Atom;
+ xevent.ClientMessageEvent.window = HoverState.Window;
+ xevent.ClientMessageEvent.message_type = HoverState.Atom;
xevent.ClientMessageEvent.format = 32;
xevent.ClientMessageEvent.ptr1 = (IntPtr) (HoverState.Y << 16 | HoverState.X);
- MessageQueue.EnqueueLocked (xevent);
+ hwnd.Queue.EnqueueLocked (xevent);
WakeupMain ();
}
internal override int Caption {
get {
- return 25;
+ return 19;
}
}
}
}
+ internal override Size MouseHoverSize {
+ get {
+ return new Size (1, 1);
+ }
+ }
+
+ internal override int MouseHoverTime {
+ get {
+ return HoverState.Interval;
+ }
+ }
+
+
+
internal override bool MouseWheelPresent {
get {
return true; // FIXME - how to detect?
internal override Rectangle WorkingArea {
get {
- Atom actual_atom;
+ IntPtr actual_atom;
int actual_format;
- int nitems;
- int bytes_after;
+ IntPtr nitems;
+ IntPtr bytes_after;
IntPtr prop = IntPtr.Zero;
int width;
int height;
- XGetWindowProperty(DisplayHandle, RootWindow, NetAtoms[(int)NA._NET_DESKTOP_GEOMETRY], 0, 256, false, Atom.XA_CARDINAL, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
- if ((nitems == 2) && (prop != IntPtr.Zero)) {
- width = Marshal.ReadInt32(prop, 0);
- height = Marshal.ReadInt32(prop, 4);
+ XGetWindowProperty(DisplayHandle, RootWindow, NetAtoms[(int)NA._NET_DESKTOP_GEOMETRY], IntPtr.Zero, new IntPtr (256), false, (IntPtr)Atom.XA_CARDINAL, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
+ if (((long)nitems == 2) && (prop != IntPtr.Zero) && IntPtr.Size == 4) {
+ width = Marshal.ReadIntPtr(prop, 0).ToInt32();
+ height = Marshal.ReadIntPtr(prop, IntPtr.Size).ToInt32();
XFree(prop);
return new Rectangle(0, 0, width, height);
hwnd = Hwnd.ObjectFromHandle(handle);
if (hwnd != null) lock (XlibLock) {
- SendNetWMMessage(hwnd.whole_window, (IntPtr)NetAtoms[(int)NA._NET_ACTIVE_WINDOW], IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
+ SendNetWMMessage(hwnd.whole_window, NetAtoms[(int)NA._NET_ACTIVE_WINDOW], IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
//XRaiseWindow(DisplayHandle, handle);
}
return;
internal override void CaretVisible(IntPtr handle, bool visible) {
- // Visible is cumulative; two hides require two shows before the caret is visible again
if (Caret.Hwnd == handle) {
if (visible) {
- if (Caret.Visible < 1) {
- Caret.Visible++;
- Caret.On = false;
- if (Caret.Visible == 1) {
- ShowCaret();
- Caret.Timer.Start();
- }
+ if (!Caret.Visible) {
+ Caret.Visible = true;
+ ShowCaret();
+ Caret.Timer.Start();
}
} else {
- Caret.Visible--;
- if (Caret.Visible == 0) {
- Caret.Timer.Stop();
- HideCaret();
- }
+ Caret.Visible = false;
+ Caret.Timer.Stop();
+ HideCaret();
}
}
}
- internal override bool CalculateWindowRect(IntPtr handle, ref Rectangle ClientRect, int Style, int ExStyle, Menu menu, out Rectangle WindowRect) {
+ internal override bool CalculateWindowRect(ref Rectangle ClientRect, int Style, int ExStyle, Menu menu, out Rectangle WindowRect) {
FormBorderStyle border_style;
TitleStyle title_style;
int caption_height;
int tool_caption_height;
- DeriveStyles(handle, Style, ExStyle, out border_style, out title_style,
+ DeriveStyles(Style, ExStyle, out border_style, out title_style,
out caption_height, out tool_caption_height);
WindowRect = Hwnd.GetWindowRectangle(border_style, menu, title_style,
caption_height, tool_caption_height,
ClientRect);
-
return true;
}
Clipboard.Formats = new ArrayList();
while (f != null) {
- XConvertSelection(DisplayHandle, NetAtoms[(int)NA.CLIPBOARD], f.Id, f.Id, FosterParent, IntPtr.Zero);
+ XConvertSelection(DisplayHandle, NetAtoms[(int)NA.CLIPBOARD], (IntPtr)f.Id, (IntPtr)f.Id, FosterParent, IntPtr.Zero);
Clipboard.Enumerating = true;
while (Clipboard.Enumerating) {
- UpdateMessageQueue();
+ UpdateMessageQueue(null);
}
f = f.Next;
}
result = new int[Clipboard.Formats.Count];
for (int i = 0; i < Clipboard.Formats.Count; i++) {
- result[i] = (int)Clipboard.Formats[i];
+ result[i] = ((IntPtr)Clipboard.Formats[i]).ToInt32 ();
}
Clipboard.Formats = null;
//else if (format == "SymbolicLink" ) return 4;
//else if (format == "DataInterchangeFormat" ) return 5;
//else if (format == "Tiff" ) return 6;
- else if (format == "OEMText" ) return XInternAtom(DisplayHandle, "COMPOUND_TEXT", false);
+ else if (format == "OEMText" ) return XInternAtom(DisplayHandle, "COMPOUND_TEXT", false).ToInt32();
else if (format == "DeviceIndependentBitmap" ) return (int)Atom.XA_PIXMAP;
else if (format == "Palette" ) return (int)Atom.XA_COLORMAP; // Useless
//else if (format == "PenData" ) return 10;
//else if (format == "RiffAudio" ) return 11;
//else if (format == "WaveAudio" ) return 12;
- else if (format == "UnicodeText" ) return XInternAtom(DisplayHandle, "UTF8_STRING", false);
+ else if (format == "UnicodeText" ) return XInternAtom(DisplayHandle, "UTF8_STRING", false).ToInt32();
//else if (format == "EnhancedMetafile" ) return 14;
//else if (format == "FileDrop" ) return 15;
//else if (format == "Locale" ) return 16;
- return XInternAtom(DisplayHandle, format, false);
+ return XInternAtom(DisplayHandle, format, false).ToInt32();
}
internal override IntPtr ClipboardOpen() {
}
internal override object ClipboardRetrieve(IntPtr handle, int type, XplatUI.ClipboardToObject converter) {
- XConvertSelection(DisplayHandle, NetAtoms[(int)NA.CLIPBOARD], type, type, FosterParent, IntPtr.Zero);
+ XConvertSelection(DisplayHandle, NetAtoms[(int)NA.CLIPBOARD], (IntPtr)type, (IntPtr)type, FosterParent, IntPtr.Zero);
Clipboard.Retrieving = true;
while (Clipboard.Retrieving) {
- UpdateMessageQueue();
+ UpdateMessageQueue(null);
}
return Clipboard.Item;
Caret.Window = hwnd.client_window;
Caret.Width = width;
Caret.Height = height;
- Caret.Visible = 0;
+ Caret.Visible = false;
Caret.On = false;
gc_values = new XGCValues();
gc_values.line_width = width;
- Caret.gc = XCreateGC(DisplayHandle, Caret.Window, GCFunction.GCLineWidth, ref gc_values);
+ Caret.gc = XCreateGC(DisplayHandle, Caret.Window, new IntPtr ((int)GCFunction.GCLineWidth), ref gc_values);
if (Caret.gc == IntPtr.Zero) {
Caret.Hwnd = IntPtr.Zero;
return;
Attributes.win_gravity = Gravity.NorthWestGravity;
// Save what's under the toolwindow
- if ((cp.ExStyle & (int)WindowStyles.WS_EX_TOOLWINDOW) != 0) {
+ if ((cp.ExStyle & (int)WindowExStyles.WS_EX_TOOLWINDOW) != 0) {
Attributes.save_under = true;
ValueMask |= SetWindowValuemask.SaveUnder;
}
ClientWindow = IntPtr.Zero;
lock (XlibLock) {
- WholeWindow = XCreateWindow(DisplayHandle, ParentHandle, X, Y, Width, Height, 0, (int)CreateWindowArgs.CopyFromParent, (int)CreateWindowArgs.InputOutput, IntPtr.Zero, ValueMask, ref Attributes);
+ WholeWindow = XCreateWindow(DisplayHandle, ParentHandle, X, Y, Width, 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);
ValueMask = SetWindowValuemask.ColorMap;
Attributes.colormap = CustomColormap;
}
- ClientWindow = XCreateWindow(DisplayHandle, WholeWindow, ClientRect.X, ClientRect.Y, ClientRect.Width, ClientRect.Height, 0, (int)CreateWindowArgs.CopyFromParent, (int)CreateWindowArgs.InputOutput, CustomVisual, ValueMask, ref Attributes);
+ ClientWindow = XCreateWindow(DisplayHandle, WholeWindow, ClientRect.X, ClientRect.Y, ClientRect.Width, ClientRect.Height, 0, (int)CreateWindowArgs.CopyFromParent, (int)CreateWindowArgs.InputOutput, CustomVisual, new UIntPtr ((uint)ValueMask), ref Attributes);
}
}
throw new Exception("Could not create X11 windows");
}
+ hwnd.Queue = ThreadQueue(Thread.CurrentThread);
hwnd.WholeWindow = WholeWindow;
hwnd.ClientWindow = ClientWindow;
- #if DriverDebug
- Console.WriteLine("Created window {0:X} / {1:X} parent {2:X}", ClientWindow.ToInt32(), WholeWindow.ToInt32(), hwnd.parent != null ? hwnd.parent.Handle.ToInt32() : 0);
+ #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 ((cp.Style & (int)WindowStyles.WS_CHILD) == 0) {
+ 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;
+ XSetWMNormalHints(DisplayHandle, WholeWindow, ref hints);
+ }
+ }
+
lock (XlibLock) {
- XSelectInput(DisplayHandle, hwnd.whole_window, SelectInputMask);
- XSelectInput(DisplayHandle, hwnd.client_window, SelectInputMask);
+ XSelectInput(DisplayHandle, hwnd.whole_window, new IntPtr ((int)SelectInputMask));
+ XSelectInput(DisplayHandle, hwnd.client_window, new IntPtr ((int)SelectInputMask));
if ((cp.Style & (int)WindowStyles.WS_VISIBLE) != 0) {
- XMapWindow(DisplayHandle, hwnd.whole_window);
- XMapWindow(DisplayHandle, hwnd.client_window);
+ MapWindow(hwnd, WindowType.Both);
hwnd.visible = true;
}
}
+ if ((cp.ExStyle & (int)WindowExStyles.WS_EX_TOPMOST) != 0) {
+ XSetTransientForHint (DisplayHandle, hwnd.whole_window, RootWindow);
+ } else if ((cp.ExStyle & (int)WindowExStyles.WS_EX_APPWINDOW) == 0) {
+ XSetTransientForHint (DisplayHandle, hwnd.whole_window, FosterParent);
+ }
+
SetWMStyles(hwnd, cp);
+ if ((cp.Style & (int)WindowStyles.WS_MINIMIZE) != 0) {
+ SetWindowState(hwnd.Handle, FormWindowState.Minimized);
+ } else if ((cp.Style & (int)WindowStyles.WS_MAXIMIZE) != 0) {
+ SetWindowState(hwnd.Handle, FormWindowState.Maximized);
+ }
+
// for now make all windows dnd enabled
Dnd.SetAllowDrop (hwnd, true);
}
internal override IntPtr DefWndProc(ref Message msg) {
+ switch ((Msg)msg.Msg) {
+ case Msg.WM_PAINT: {
+ Hwnd hwnd;
+
+ hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
+ if (hwnd != null) {
+ hwnd.expose_pending = false;
+ }
+
+ return IntPtr.Zero;
+ }
+
+ case Msg.WM_NCPAINT: {
+ Hwnd hwnd;
+
+ hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
+ if (hwnd != null) {
+ hwnd.nc_expose_pending = false;
+ }
+
+ return IntPtr.Zero;
+ }
+
+ case Msg.WM_CONTEXTMENU: {
+ Hwnd hwnd;
+
+ hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
+
+ if ((hwnd != null) && (hwnd.parent != null)) {
+ SendMessage(hwnd.parent.client_window, Msg.WM_CONTEXTMENU, msg.WParam, msg.LParam);
+ }
+ return IntPtr.Zero;
+ }
+
+ case Msg.WM_SETCURSOR: {
+ Hwnd hwnd;
+
+ hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
+ if (hwnd == null)
+ break; // not sure how this happens, but it does
+
+ // Pass to parent window first
+ while ((hwnd.parent != null) && (msg.Result == IntPtr.Zero)) {
+ hwnd = hwnd.parent;
+ msg.Result = NativeWindow.WndProc(hwnd.Handle, Msg.WM_SETCURSOR, msg.HWnd, msg.LParam);
+ }
+
+ if (msg.Result == IntPtr.Zero) {
+ IntPtr handle;
+
+ switch((HitTest)(msg.LParam.ToInt32() & 0xffff)) {
+ case HitTest.HTBOTTOM: handle = Cursors.SizeNS.handle; break;
+ case HitTest.HTBORDER: handle = Cursors.SizeNS.handle; break;
+ case HitTest.HTBOTTOMLEFT: handle = Cursors.SizeNESW.handle; break;
+ case HitTest.HTBOTTOMRIGHT: handle = Cursors.SizeNWSE.handle; break;
+ case HitTest.HTERROR: if ((msg.LParam.ToInt32() >> 16) == (int)Msg.WM_LBUTTONDOWN) {
+ AudibleAlert();
+ }
+ handle = Cursors.Default.handle;
+ break;
+
+ case HitTest.HTHELP: handle = Cursors.Help.handle; break;
+ case HitTest.HTLEFT: handle = Cursors.SizeWE.handle; break;
+ case HitTest.HTRIGHT: handle = Cursors.SizeWE.handle; break;
+ case HitTest.HTTOP: handle = Cursors.SizeNS.handle; break;
+ case HitTest.HTTOPLEFT: handle = Cursors.SizeNWSE.handle; break;
+ case HitTest.HTTOPRIGHT: handle = Cursors.SizeNESW.handle; break;
+
+ #if SameAsDefault
+ case HitTest.HTGROWBOX:
+ case HitTest.HTSIZE:
+ case HitTest.HTZOOM:
+ case HitTest.HTVSCROLL:
+ case HitTest.HTSYSMENU:
+ case HitTest.HTREDUCE:
+ case HitTest.HTNOWHERE:
+ case HitTest.HTMAXBUTTON:
+ case HitTest.HTMINBUTTON:
+ case HitTest.HTMENU:
+ case HitTest.HSCROLL:
+ case HitTest.HTBOTTOM:
+ case HitTest.HTCAPTION:
+ case HitTest.HTCLIENT:
+ case HitTest.HTCLOSE:
+ #endif
+ default: handle = Cursors.Default.handle; break;
+ }
+ SetCursor(msg.HWnd, handle);
+ }
+ return (IntPtr)1;
+ }
+ }
return IntPtr.Zero;
}
internal override void DestroyCaret(IntPtr handle) {
if (Caret.Hwnd == handle) {
- if (Caret.Visible == 1) {
+ if (Caret.Visible == true) {
Caret.Timer.Stop();
HideCaret();
}
Caret.gc = IntPtr.Zero;
}
Caret.Hwnd = IntPtr.Zero;
- Caret.Visible = 0;
+ Caret.Visible = false;
Caret.On = false;
}
}
+ private void DestroyCaretInternal() {
+ if (Caret.Visible == true) {
+ Caret.Timer.Stop();
+ }
+ if (Caret.gc != IntPtr.Zero) {
+ XFreeGC(DisplayHandle, Caret.gc);
+ Caret.gc = IntPtr.Zero;
+ }
+ Caret.Hwnd = IntPtr.Zero;
+ Caret.Visible = false;
+ Caret.On = false;
+ }
+
internal override void DestroyCursor(IntPtr cursor) {
lock (XlibLock) {
XFreeCursor(DisplayHandle, cursor);
hwnd = Hwnd.ObjectFromHandle(handle);
if (hwnd == null) {
- #if DriverDebug
+ #if DriverDebug || DriverDebugDestroy
Console.WriteLine("window {0:X} already destroyed", handle.ToInt32());
#endif
return;
}
- #if DriverDebug
+ #if DriverDebug || DriverDebugDestroy
Console.WriteLine("Destroying window {0:X}", handle.ToInt32());
#endif
DestroyCaret(handle);
}
- // The window is a goner, don't send it stuff like WM_PAINT anymore
- hwnd.destroy_pending = true;
+ if (ActiveWindow == handle) {
+ SendMessage(handle, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_INACTIVE, IntPtr.Zero);
+ ActiveWindow = IntPtr.Zero;
+ }
- // Mark our children as gone as well
- DestroyChildWindow(Control.ControlNativeWindow.ControlFromHandle(handle));
+ SendWMDestroyMessages(Control.ControlNativeWindow.ControlFromHandle(hwnd.Handle));
lock (XlibLock) {
if (hwnd.client_window != IntPtr.Zero) {
XDestroyWindow(DisplayHandle, hwnd.whole_window);
}
}
+ hwnd.Dispose();
}
internal override IntPtr DispatchMessage(ref MSG msg) {
//XSetPlaneMask(DisplayHandle, gc, mask);
- gc = XCreateGC(DisplayHandle, hwnd.client_window, GCFunction.GCSubwindowMode | GCFunction.GCLineWidth | GCFunction.GCForeground, ref gc_values);
+ gc = XCreateGC(DisplayHandle, hwnd.client_window, new IntPtr ((int) (GCFunction.GCSubwindowMode | GCFunction.GCLineWidth | GCFunction.GCForeground)), ref gc_values);
uint foreground;
uint background;
uint mask = foreground ^ background;
- XSetForeground(DisplayHandle, gc, 0xffffffff);
- XSetBackground(DisplayHandle, gc, background);
+ XSetForeground(DisplayHandle, gc, (UIntPtr)0xffffffff);
+ XSetBackground(DisplayHandle, gc, (UIntPtr)background);
XSetFunction(DisplayHandle, gc, GXFunction.GXxor);
- XSetPlaneMask(DisplayHandle, gc, mask);
+ XSetPlaneMask(DisplayHandle, gc, (IntPtr)mask);
if ((rect.Width > 0) && (rect.Height > 0)) {
XDrawRectangle(DisplayHandle, hwnd.client_window, gc, rect.Left, rect.Top, rect.Width, rect.Height);
}
internal override void DoEvents() {
- MSG msg = new MSG ();
+ MSG msg = new MSG ();
+ Object queue_id;
if (OverrideCursorHandle != IntPtr.Zero) {
OverrideCursorHandle = IntPtr.Zero;
}
- while (PeekMessage(ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)) {
- if (msg.message == Msg.WM_PAINT) {
- TranslateMessage (ref msg);
- DispatchMessage (ref msg);
- }
+ queue_id = (Object)ThreadQueue(Thread.CurrentThread);
+
+ while (PeekMessage(queue_id, ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)) {
+ TranslateMessage (ref msg);
+ DispatchMessage (ref msg);
}
}
}
}
+ internal override void EndLoop(Thread thread) {
+ // This is where we one day will shut down the loop for the thread
+ }
+
+
internal override IntPtr GetActive() {
- Atom actual_atom;
+ IntPtr actual_atom;
int actual_format;
- int nitems;
- int bytes_after;
+ IntPtr nitems;
+ IntPtr bytes_after;
IntPtr prop = IntPtr.Zero;
IntPtr active = IntPtr.Zero;
- XGetWindowProperty(DisplayHandle, RootWindow, NetAtoms[(int)NA._NET_ACTIVE_WINDOW], 0, 1, false, Atom.XA_WINDOW, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
- if ((nitems > 0) && (prop != IntPtr.Zero)) {
+ XGetWindowProperty(DisplayHandle, RootWindow, NetAtoms[(int)NA._NET_ACTIVE_WINDOW], IntPtr.Zero, new IntPtr (1), false, (IntPtr)Atom.XA_WINDOW, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
+ if (((long)nitems > 0) && (prop != IntPtr.Zero)) {
active = (IntPtr)Marshal.ReadInt32(prop);
XFree(prop);
}
return active;
}
+ internal override Region GetClipRegion(IntPtr handle) {
+ Hwnd hwnd;
+
+ hwnd = Hwnd.ObjectFromHandle(handle);
+ if (hwnd != null) {
+ return hwnd.UserClip;
+ }
+
+ return null;
+ }
+
internal override void GetCursorInfo(IntPtr cursor, out int width, out int height, out int hotspot_x, out int hotspot_y) {
- throw new NotImplementedException ();
+ width = 20;
+ height = 20;
+ hotspot_x = 0;
+ hotspot_y = 0;
}
internal override void GetDisplaySize(out Size size) {
return GetFontMetrics(g.GetHdc(), font.ToHfont(), out ascent, out descent);
}
- internal override Graphics GetMenuDC(IntPtr handle, IntPtr ncpaint_region) {
- Hwnd hwnd;
-
- hwnd = Hwnd.ObjectFromHandle(handle);
-
- return Graphics.FromHwnd(hwnd.whole_window);
- }
-
internal override Point GetMenuOrigin(IntPtr handle) {
Hwnd hwnd;
return Point.Empty;
}
- internal override bool GetMessage(ref MSG msg, IntPtr handle, int wFilterMin, int wFilterMax) {
+ [MonoTODO("Implement filtering")]
+ internal override bool GetMessage(Object queue_id, ref MSG msg, IntPtr handle, int wFilterMin, int wFilterMax) {
XEvent xevent;
bool client;
Hwnd hwnd;
ProcessNextMessage:
- if (MessageQueue.Count > 0) {
- xevent = (XEvent) MessageQueue.Dequeue ();
+ if (((XEventQueue)queue_id).Count > 0) {
+ xevent = (XEvent) ((XEventQueue)queue_id).Dequeue ();
} else {
- UpdateMessageQueue ();
+ UpdateMessageQueue ((XEventQueue)queue_id);
- if (MessageQueue.Count > 0) {
- xevent = (XEvent) MessageQueue.Dequeue ();
+ if (((XEventQueue)queue_id).Count > 0) {
+ xevent = (XEvent) ((XEventQueue)queue_id).Dequeue ();
+ } else if (((XEventQueue)queue_id).Paint.Count > 0) {
+ xevent = ((XEventQueue)queue_id).Paint.Dequeue();
} else {
if (!PostQuitState) {
msg.hwnd= IntPtr.Zero;
}
}
- // FIXME - handle filtering
-
hwnd = Hwnd.GetObjectFromWindow(xevent.AnyEvent.window);
// Handle messages for windows that are already or are about to be destroyed
- if (hwnd == null || hwnd.destroy_pending) {
- // We need to let the DestroyNotify go through so that the owning control can learn about it, too
- if (hwnd == null || xevent.type != XEventName.DestroyNotify) {
- #if DriverDebug
- Console.WriteLine("GetMessage(): Got message {0} for non-existent or already destroyed window {1:X}", xevent.type, xevent.AnyEvent.window.ToInt32());
- #endif
- goto ProcessNextMessage;
- }
+ if (hwnd == null) {
+ #if DriverDebug
+ Console.WriteLine("GetMessage(): Got message {0} for non-existent or already destroyed window {1:X}", xevent.type, xevent.AnyEvent.window.ToInt32());
+ #endif
+ goto ProcessNextMessage;
}
if (hwnd.client_window == xevent.AnyEvent.window) {
}
case XEventName.ButtonRelease: {
- Dnd.HandleButtonRelease (ref xevent);
+ if (Dnd.InDrag()) {
+ Dnd.HandleButtonRelease (ref xevent);
+ break;
+ }
+
switch(xevent.ButtonEvent.button) {
case 1: {
MouseState &= ~MouseButtons.Left;
msg.lParam = (IntPtr)(MousePosition.Y << 16 | MousePosition.X);
}
- HoverState.X = MousePosition.X = xevent.MotionEvent.x;
- HoverState.Y = MousePosition.Y = xevent.MotionEvent.y;
+ MousePosition.X = xevent.MotionEvent.x;
+ MousePosition.Y = xevent.MotionEvent.y;
+
+ if ((HoverState.Timer.Enabled) &&
+ (((MousePosition.X + HoverState.Size.Width) < HoverState.X) ||
+ ((MousePosition.X - HoverState.Size.Width) > HoverState.X) ||
+ ((MousePosition.Y + HoverState.Size.Height) < HoverState.Y) ||
+ ((MousePosition.Y - HoverState.Size.Height) > HoverState.Y))) {
+ HoverState.Timer.Stop();
+ HoverState.Timer.Start();
+ HoverState.X = MousePosition.X;
+ HoverState.Y = MousePosition.Y;
+ }
break;
} else {
+ HitTest ht;
+ IntPtr dummy;
+ int screen_x;
+ int screen_y;
+
#if DriverDebugExtra
Console.WriteLine("GetMessage(): non-client area {0:X} MotionNotify x={1} y={2}", client ? hwnd.client_window.ToInt32() : hwnd.whole_window.ToInt32(), xevent.MotionEvent.x, xevent.MotionEvent.y);
#endif
msg.message = Msg.WM_NCMOUSEMOVE;
- msg.lParam = (IntPtr) (xevent.MotionEvent.y << 16 | xevent.MotionEvent.x & 0xFFFF);
if (!hwnd.Enabled) {
- IntPtr dummy;
-
msg.hwnd = hwnd.EnabledHwnd;
XTranslateCoordinates(DisplayHandle, xevent.AnyEvent.window, Hwnd.ObjectFromHandle(msg.hwnd).ClientWindow, xevent.MotionEvent.x, xevent.MotionEvent.y, out xevent.MotionEvent.x, out xevent.MotionEvent.y, out dummy);
msg.lParam = (IntPtr)(MousePosition.Y << 16 | MousePosition.X);
}
- #if notyet
- // Not sure we need this...
- HitTest ht;
- ht = NativeWindow.WndProc(hwnd.client_window, Msg.WM_NCHITTEST, IntPtr.Zero, msg.lParam);
- #endif
+ // The hit test is sent in screen coordinates
+ XTranslateCoordinates (DisplayHandle, hwnd.client_window, RootWindow,
+ xevent.MotionEvent.x, xevent.MotionEvent.y,
+ out screen_x, out screen_y, out dummy);
+
+ msg.lParam = (IntPtr) (screen_y << 16 | screen_x & 0xFFFF);
+ ht = (HitTest)NativeWindow.WndProc (hwnd.client_window, Msg.WM_NCHITTEST,
+ IntPtr.Zero, msg.lParam).ToInt32 ();
+ NativeWindow.WndProc(hwnd.client_window, Msg.WM_SETCURSOR, msg.hwnd, (IntPtr)ht);
MousePosition.X = xevent.MotionEvent.x;
MousePosition.Y = xevent.MotionEvent.y;
goto ProcessNextMessage;
}
msg.message = Msg.WM_MOUSE_ENTER;
+ HoverState.X = xevent.CrossingEvent.x;
+ HoverState.Y = xevent.CrossingEvent.y;
HoverState.Timer.Enabled = true;
HoverState.Window = xevent.CrossingEvent.window;
break;
if (!hwnd.Enabled) {
goto ProcessNextMessage;
}
- if (xevent.CrossingEvent.mode != NotifyMode.NotifyNormal) {
+ if ((xevent.CrossingEvent.mode != NotifyMode.NotifyNormal) || (xevent.CrossingEvent.window != hwnd.client_window)) {
goto ProcessNextMessage;
}
msg.message=Msg.WM_MOUSE_LEAVE;
case XEventName.ReparentNotify: {
if (hwnd.parent == null) { // Toplevel
- if (xevent.ReparentEvent.parent != IntPtr.Zero) {
+ if ((xevent.ReparentEvent.parent != IntPtr.Zero) && (xevent.ReparentEvent.window == hwnd.whole_window)) {
// We need to adjust x/y
+ // This sucks ass, part 2
+ // Every WM does the reparenting of toplevel windows different, so there's
+ // no standard way of getting our adjustment considering frames/decorations
+ // The code below is needed for metacity. KDE doesn't works just fine without this
int dummy_int;
IntPtr dummy_ptr;
+ int new_x;
+ int new_y;
+ int frame_left;
+ int frame_top;
hwnd.Reparented = true;
- XGetGeometry(DisplayHandle, XGetParent(hwnd.whole_window), out dummy_ptr, out hwnd.x, out hwnd.y, out dummy_int, out dummy_int, out dummy_int, out dummy_int);
- msg.message = Msg.WM_WINDOWPOSCHANGED;
+ XGetGeometry(DisplayHandle, XGetParent(hwnd.whole_window), out dummy_ptr, out new_x, out new_y, out dummy_int, out dummy_int, out dummy_int, out dummy_int);
+ FrameExtents(hwnd.whole_window, out frame_left, out frame_top);
+ if ((frame_left != 0) && (frame_top != 0) && (new_x != frame_left) && (new_y != frame_top)) {
+ hwnd.x = new_x;
+ hwnd.y = new_y;
+ hwnd.whacky_wm = true;
+ }
+
+ if (hwnd.opacity != 0xffffffff) {
+ IntPtr opacity;
+ opacity = (IntPtr)(Int32)hwnd.opacity;
+ XChangeProperty(DisplayHandle, XGetParent(hwnd.whole_window), NetAtoms[(int)NA._NET_WM_WINDOW_OPACITY], (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, ref opacity, 1);
+ }
+ SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, msg.wParam, msg.lParam);
+ goto ProcessNextMessage;
} else {
hwnd.Reparented = false;
goto ProcessNextMessage;
}
}
- break;
+ goto ProcessNextMessage;
}
case XEventName.ConfigureNotify: {
- if (!client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) { // Ignore events for children (SubstructureNotify) and client areas
- XplatUIWin32.NCCALCSIZE_PARAMS ncp;
- IntPtr ptr;
- Rectangle rect;
-
+ if (PostQuitState || !client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) { // Ignore events for children (SubstructureNotify) and client areas
#if DriverDebugExtra
Console.WriteLine("GetMessage(): Window {0:X} ConfigureNotify x={1} y={2} width={3} height={4}", hwnd.client_window.ToInt32(), xevent.ConfigureEvent.x, xevent.ConfigureEvent.y, xevent.ConfigureEvent.width, xevent.ConfigureEvent.height);
#endif
- msg.message = Msg.WM_WINDOWPOSCHANGED;
+ SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
hwnd.configure_pending = false;
// We need to adjust our client window to track the resize of whole_window
- rect = hwnd.DefaultClientRect;
-
- ncp = new XplatUIWin32.NCCALCSIZE_PARAMS();
- ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ncp));
-
- ncp.rgrc1.left = rect.Left;
- ncp.rgrc1.top = rect.Top;
- ncp.rgrc1.right = rect.Right;
- ncp.rgrc1.bottom = rect.Bottom;
-
- Marshal.StructureToPtr(ncp, ptr, true);
- NativeWindow.WndProc(hwnd.client_window, Msg.WM_NCCALCSIZE, (IntPtr)1, ptr);
- ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(ptr, typeof(XplatUIWin32.NCCALCSIZE_PARAMS));
- Marshal.FreeHGlobal(ptr);
-
- // FIXME - debug this with Menus, need to set hwnd.ClientRect
-
- rect = new Rectangle(ncp.rgrc1.left, ncp.rgrc1.top, ncp.rgrc1.right - ncp.rgrc1.left, ncp.rgrc1.bottom - ncp.rgrc1.top);
-
- XMoveResizeWindow(DisplayHandle, hwnd.client_window, rect.X, rect.Y, rect.Width, rect.Height);
- } else {
- goto ProcessNextMessage;
+ PerformNCCalc(hwnd);
}
-
- msg.lParam=IntPtr.Zero; // FIXME - Generate LPWINDOWPOS structure and pass on
- break;
+ goto ProcessNextMessage;
}
case XEventName.FocusIn: {
- if (!hwnd.Enabled) {
+ // We received focus. We use X11 focus only to know if the app window does or does not have focus
+ // We do not track the actual focussed window via it. Instead, this is done via FocusWindow internally
+ // Receiving focus means we've gotten activated and therefore we need to let the actual FocusWindow know
+ // about it having focus again
+ if (xevent.FocusChangeEvent.detail != NotifyDetail.NotifyNonlinear) {
goto ProcessNextMessage;
}
- msg.message=Msg.WM_SETFOCUS;
- msg.wParam=IntPtr.Zero;
- break;
+ Keyboard.FocusIn(FocusWindow);
+ SendMessage(FocusWindow, Msg.WM_SETFOCUS, IntPtr.Zero, IntPtr.Zero);
+ goto ProcessNextMessage;
}
case XEventName.FocusOut: {
- if (!hwnd.Enabled) {
+ // Se the comment for our FocusIn handler
+ if (xevent.FocusChangeEvent.detail != NotifyDetail.NotifyNonlinear) {
goto ProcessNextMessage;
}
- msg.message=Msg.WM_KILLFOCUS;
- msg.wParam=IntPtr.Zero;
- break;
+ Keyboard.FocusOut(FocusWindow);
+
+ while (Keyboard.ResetKeyState(FocusWindow, ref msg)) {
+ SendMessage(FocusWindow, msg.message, msg.wParam, msg.lParam);
+ }
+
+ SendMessage(FocusWindow, Msg.WM_KILLFOCUS, IntPtr.Zero, IntPtr.Zero);
+ goto ProcessNextMessage;
}
case XEventName.Expose: {
- if (PostQuitState) {
+ if (PostQuitState || !hwnd.Mapped) {
+ if (client) {
+ hwnd.expose_pending = false;
+ } else {
+ hwnd.nc_expose_pending = false;
+ }
goto ProcessNextMessage;
}
-
if (client) {
if (!hwnd.expose_pending) {
goto ProcessNextMessage;
Graphics g;
g = Graphics.FromHwnd(hwnd.whole_window);
- ControlPaint.DrawBorder3D(g, new Rectangle(0, 0, hwnd.Width, hwnd.Height));
+ ControlPaint.DrawBorder3D(g, new Rectangle(0, 0, hwnd.Width, hwnd.Height), Border3DStyle.Sunken);
g.Dispose();
break;
}
IntPtr hrgn = region.GetHrgn (null); // Graphics object isn't needed
msg.message = Msg.WM_NCPAINT;
msg.wParam = hrgn;
- hwnd.nc_expose_pending = false;
break;
}
#if DriverDebugExtra
Console.WriteLine("GetMessage(): Window {0:X} Exposed area {1},{2} {3}x{4}", hwnd.client_window.ToInt32(), xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
#endif
- if (Caret.Visible == 1) {
+ if (Caret.Visible == true) {
Caret.Paused = true;
HideCaret();
}
- if (Caret.Visible == 1) {
+ if (Caret.Visible == true) {
ShowCaret();
Caret.Paused = false;
}
// We may get multiple for the same window, act only one the first (when Hwnd still knows about it)
if ((hwnd != null) && (hwnd.client_window == xevent.DestroyWindowEvent.window)) {
+ if (ActiveWindow == hwnd.client_window) {
+ SendMessage(hwnd.client_window, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_INACTIVE, IntPtr.Zero);
+ ActiveWindow = IntPtr.Zero;
+ }
+
+ if (Caret.Window == hwnd.client_window) {
+ DestroyCaretInternal();
+ }
+
+ #if DriverDebugDestroy
+ Console.WriteLine("Received X11 Destroy Notification for {0}", XplatUI.Window(hwnd.client_window));
+ #endif
+
msg.hwnd = hwnd.client_window;
msg.message=Msg.WM_DESTROY;
hwnd.Dispose();
goto ProcessNextMessage;
}
- if (xevent.ClientMessageEvent.message_type == (IntPtr)AsyncAtom) {
+ if (xevent.ClientMessageEvent.message_type == AsyncAtom) {
XplatUIDriverSupport.ExecuteClientMessage((GCHandle)xevent.ClientMessageEvent.ptr1);
- break;
+ goto ProcessNextMessage;
}
- if (xevent.ClientMessageEvent.message_type == (IntPtr)HoverState.Atom) {
+ if (xevent.ClientMessageEvent.message_type == HoverState.Atom) {
msg.message = Msg.WM_MOUSEHOVER;
msg.wParam = GetMousewParam(0);
msg.lParam = (IntPtr) (xevent.ClientMessageEvent.ptr1);
- break;
+ return true;
}
if (xevent.ClientMessageEvent.message_type == (IntPtr)PostAtom) {
msg.message = (Msg) xevent.ClientMessageEvent.ptr2.ToInt32 ();
msg.wParam = xevent.ClientMessageEvent.ptr3;
msg.lParam = xevent.ClientMessageEvent.ptr4;
- break;
+ return true;
}
#if dontcare
- if (xevent.ClientMessageEvent.message_type == (IntPtr)NetAtoms[(int)NA._XEMBED]) {
+ if (xevent.ClientMessageEvent.message_type == NetAtoms[(int)NA._XEMBED]) {
Console.WriteLine("GOT EMBED MESSAGE {0:X}", xevent.ClientMessageEvent.ptr2.ToInt32());
break;
}
#endif
- if (xevent.ClientMessageEvent.message_type == (IntPtr)NetAtoms[(int)NA.WM_PROTOCOLS]) {
- if (xevent.ClientMessageEvent.ptr1 == (IntPtr)NetAtoms[(int)NA.WM_DELETE_WINDOW]) {
+ if (xevent.ClientMessageEvent.message_type == NetAtoms[(int)NA.WM_PROTOCOLS]) {
+ if (xevent.ClientMessageEvent.ptr1 == NetAtoms[(int)NA.WM_DELETE_WINDOW]) {
msg.message = Msg.WM_CLOSE;
Graphics.FromHdcInternal (IntPtr.Zero);
- break;
+ return true;
}
// We should not get this, but I'll leave the code in case we need it in the future
- if (xevent.ClientMessageEvent.ptr1 == (IntPtr)NetAtoms[(int)NA.WM_TAKE_FOCUS]) {
+ if (xevent.ClientMessageEvent.ptr1 == NetAtoms[(int)NA.WM_TAKE_FOCUS]) {
goto ProcessNextMessage;
}
}
- break;
+ goto ProcessNextMessage;
}
case XEventName.TimerNotify: {
xevent.TimerNotifyEvent.handler (this, EventArgs.Empty);
- break;
+ goto ProcessNextMessage;
}
default: {
internal override void GetWindowPos(IntPtr handle, bool is_toplevel, out int x, out int y, out int width, out int height, out int client_width, out int client_height) {
Hwnd hwnd;
- Rectangle rect;
hwnd = Hwnd.ObjectFromHandle(handle);
width = hwnd.width;
height = hwnd.height;
- rect = Hwnd.GetClientRectangle(hwnd.border_style, hwnd.menu, hwnd.title_style, hwnd.caption_height, hwnd.tool_caption_height, width, height);
+ if (hwnd.ClientRect.IsEmpty) {
+ PerformNCCalc(hwnd);
+ }
- client_width = rect.Width;
- client_height = rect.Height;
+ client_width = hwnd.ClientRect.Width;
+ client_height = hwnd.ClientRect.Height;
return;
}
}
internal override FormWindowState GetWindowState(IntPtr handle) {
- Atom actual_atom;
+ IntPtr actual_atom;
int actual_format;
- int nitems;
- int bytes_after;
+ IntPtr nitems;
+ IntPtr bytes_after;
IntPtr prop = IntPtr.Zero;
IntPtr atom;
int maximized;
+ bool minimized;
XWindowAttributes attributes;
Hwnd hwnd;
hwnd = Hwnd.ObjectFromHandle(handle);
maximized = 0;
- XGetWindowProperty(DisplayHandle, hwnd.whole_window, NetAtoms[(int)NA._NET_WM_STATE], 0, 256, false, Atom.XA_ATOM, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
- if ((nitems > 0) && (prop != IntPtr.Zero)) {
- for (int i = 0; i < nitems; i++) {
+ minimized = false;
+ XGetWindowProperty(DisplayHandle, hwnd.whole_window, NetAtoms[(int)NA._NET_WM_STATE], IntPtr.Zero, new IntPtr (256), false, (IntPtr)Atom.XA_ATOM, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
+ if (((long)nitems > 0) && (prop != IntPtr.Zero)) {
+ for (int i = 0; i < (long)nitems; i++) {
atom = (IntPtr)Marshal.ReadInt32(prop, i * 4);
- if ((atom == (IntPtr)NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_HORZ]) || (atom == (IntPtr)NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_VERT])) {
+ if ((atom == NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_HORZ]) || (atom == NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_VERT])) {
maximized++;
+ } else if (atom == NetAtoms[(int)NA._NET_WM_STATE_HIDDEN]) {
+ minimized = true;
}
}
XFree(prop);
}
- if (maximized == 2) {
+ if (minimized) {
+ return FormWindowState.Minimized;
+ } else if (maximized == 2) {
return FormWindowState.Maximized;
}
-
attributes = new XWindowAttributes();
XGetWindowAttributes(DisplayHandle, handle, ref attributes);
if (attributes.map_state == MapState.IsUnmapped) {
- return FormWindowState.Minimized;
+ throw new NotSupportedException("Cannot retrieve the state of an unmapped window");
}
+
return FormWindowState.Normal;
}
XGrabPointer(DisplayHandle, hwnd.client_window, false,
EventMask.ButtonPressMask | EventMask.ButtonMotionMask |
EventMask.ButtonReleaseMask | EventMask.PointerMotionMask,
- GrabMode.GrabModeAsync, GrabMode.GrabModeAsync, confine_to_window, 0, 0);
+ GrabMode.GrabModeAsync, GrabMode.GrabModeAsync, confine_to_window, IntPtr.Zero, IntPtr.Zero);
}
}
internal override void UngrabWindow(IntPtr hwnd) {
lock (XlibLock) {
- XUngrabPointer(DisplayHandle, 0);
+ XUngrabPointer(DisplayHandle, IntPtr.Zero);
XFlush(DisplayHandle);
}
Grab.Hwnd = IntPtr.Zero;
internal override void Invalidate(IntPtr handle, Rectangle rc, bool clear) {
Hwnd hwnd;
- XEvent xevent;
hwnd = Hwnd.ObjectFromHandle(handle);
-
- xevent = new XEvent ();
- xevent.type = XEventName.Expose;
- xevent.ExposeEvent.display = DisplayHandle;
- xevent.ExposeEvent.window = hwnd.client_window;
-
if (clear) {
- xevent.ExposeEvent.x = hwnd.X;
- xevent.ExposeEvent.y = hwnd.Y;
- xevent.ExposeEvent.width = hwnd.Width;
- xevent.ExposeEvent.height = hwnd.Height;
+ AddExpose (hwnd, true, hwnd.X, hwnd.Y, hwnd.Width, hwnd.Height);
} else {
- xevent.ExposeEvent.x = rc.X;
- xevent.ExposeEvent.y = rc.Y;
- xevent.ExposeEvent.width = rc.Width;
- xevent.ExposeEvent.height = rc.Height;
+ AddExpose (hwnd, true, rc.X, rc.Y, rc.Width, rc.Height);
}
-
- AddExpose (xevent);
}
internal override bool IsEnabled(IntPtr handle) {
hwnd = Hwnd.ObjectFromHandle(handle);
- if (Caret.Visible == 1) {
+ if (Caret.Visible == true) {
Caret.Paused = true;
HideCaret();
}
-
+
if (client) {
+#if true
hwnd.client_dc = Graphics.FromHwnd (hwnd.client_window);
- hwnd.client_dc.SetClip(hwnd.invalid);
- paint_event = new PaintEventArgs(hwnd.client_dc, hwnd.invalid);
+#else
+ // Protected against illegal cross-thread painting
+ lock (XlibLock) {
+ if (hwnd.client_dc != null) {
+ return null;
+ }
+
+ hwnd.client_dc = Graphics.FromHwnd (hwnd.client_window);
+ }
+#endif
+
+ Region clip_region = new Region ();
+ clip_region.MakeEmpty();
+
+ foreach (Rectangle r in hwnd.ClipRectangles) {
+ clip_region.Union (r);
+ }
+
+ if (hwnd.UserClip != null) {
+ clip_region.Intersect(hwnd.UserClip);
+ }
+
+ hwnd.client_dc.Clip = clip_region;
+ paint_event = new PaintEventArgs(hwnd.client_dc, hwnd.Invalid);
hwnd.expose_pending = false;
return paint_event;
} else {
- hwnd.client_dc = Graphics.FromHwnd (hwnd.whole_window);
- paint_event = new PaintEventArgs(hwnd.client_dc, new Rectangle(0, 0, hwnd.width, hwnd.height));
+ hwnd.non_client_dc = Graphics.FromHwnd (hwnd.whole_window);
+
+ if (!hwnd.nc_invalid.IsEmpty) {
+ hwnd.non_client_dc.SetClip (hwnd.nc_invalid);
+ paint_event = new PaintEventArgs(hwnd.non_client_dc, hwnd.nc_invalid);
+ } else {
+ paint_event = new PaintEventArgs(hwnd.non_client_dc, new Rectangle(0, 0, hwnd.width, hwnd.height));
+ }
hwnd.nc_expose_pending = false;
return paint_event;
if (client) {
hwnd.ClearInvalidArea();
+
+#if true
+ hwnd.client_dc.Flush();
+ hwnd.client_dc.Dispose();
+ hwnd.client_dc = null;
+#else
+ lock (XlibLock) {
+ hwnd.client_dc.Flush();
+ hwnd.client_dc.Dispose();
+ hwnd.client_dc = null;
+ }
+#endif
+ } else {
+ hwnd.ClearNcInvalidArea ();
+
+ hwnd.non_client_dc.Flush ();
+ hwnd.non_client_dc.Dispose ();
+ hwnd.non_client_dc = null;
}
- hwnd.client_dc.Flush();
- hwnd.client_dc.Dispose();
- hwnd.client_dc = null;
+
- if (Caret.Visible == 1) {
+ if (Caret.Visible == true) {
ShowCaret();
Caret.Paused = false;
}
}
- internal override bool PeekMessage(ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags) {
+ [MonoTODO("Implement filtering and PM_NOREMOVE")]
+ internal override bool PeekMessage(Object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags) {
bool pending;
- // FIXME - imlement filtering
-
if ((flags & (uint)PeekMessageFlags.PM_REMOVE) == 0) {
throw new NotImplementedException("PeekMessage PM_NOREMOVE is not implemented yet"); // FIXME - Implement PM_NOREMOVE flag
}
pending = false;
- if (MessageQueue.Count > 0) {
+ if (((XEventQueue)queue_id).Count > 0) {
pending = true;
} else {
// Only call UpdateMessageQueue if real events are pending
// otherwise we go to sleep on the socket
if (XPending(DisplayHandle) != 0) {
- UpdateMessageQueue();
+ UpdateMessageQueue((XEventQueue)queue_id);
+ pending = true;
+ } else if (((XEventQueue)queue_id).Paint.Count > 0) {
pending = true;
}
}
if (!pending) {
return false;
}
- return GetMessage(ref msg, hWnd, wFilterMin, wFilterMax);
+ return GetMessage(queue_id, ref msg, hWnd, wFilterMin, wFilterMax);
}
// FIXME - I think this should just enqueue directly
xevent.ClientMessageEvent.ptr3 = wparam;
xevent.ClientMessageEvent.ptr4 = lparam;
- MessageQueue.Enqueue (xevent);
+ hwnd.Queue.Enqueue (xevent);
return true;
}
Graphics.FromHdcInternal (IntPtr.Zero);
}
- internal override void ReleaseMenuDC(IntPtr handle, Graphics dc) {
- dc.Dispose();
+ internal override void RequestNCRecalc(IntPtr handle) {
+ Hwnd hwnd;
+
+ hwnd = Hwnd.ObjectFromHandle(handle);
+
+ if (hwnd == null) {
+ return;
+ }
+
+ PerformNCCalc(hwnd);
+ SendMessage(handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
+ InvalidateWholeWindow(handle);
+ }
+
+ internal override void ResetMouseHover(IntPtr handle) {
+ Hwnd hwnd;
+
+ hwnd = Hwnd.ObjectFromHandle(handle);
+ if (hwnd == null) {
+ return;
+ }
+
+ HoverState.Timer.Enabled = true;
+ HoverState.X = MousePosition.X;
+ HoverState.Y = MousePosition.Y;
+ HoverState.Window = handle;
}
+
internal override void ScreenToClient(IntPtr handle, ref int x, ref int y) {
int dest_x_return;
int dest_y_return;
Hwnd hwnd;
IntPtr gc;
XGCValues gc_values;
+ Rectangle r;
hwnd = Hwnd.ObjectFromHandle(handle);
- if (hwnd.invalid != Rectangle.Empty) {
- // BIG FAT WARNING. This only works with how we use this function right now
- // where we basically still scroll the whole window, but work around areas
- // that are covered by our children
+ r = hwnd.Invalid;
+ if (r != Rectangle.Empty) {
+ /* We have an invalid area in the window we're scrolling.
+ Adjust our stored invalid rectangle to to match the scrolled amount */
- hwnd.invalid.X += XAmount;
- hwnd.invalid.Y += YAmount;
+ r.X += XAmount;
+ r.Y += YAmount;
- if (hwnd.invalid.X < 0) {
- hwnd.invalid.Width += hwnd.invalid.X;
- hwnd.invalid.X =0;
+ if (r.X < 0) {
+ r.Width += r.X;
+ r.X =0;
}
- if (hwnd.invalid.Y < 0) {
- hwnd.invalid.Height += hwnd.invalid.Y;
- hwnd.invalid.Y =0;
+ if (r.Y < 0) {
+ r.Height += r.Y;
+ r.Y =0;
}
+
+ hwnd.ClearInvalidArea();
+ hwnd.AddInvalidArea(r);
}
gc_values = new XGCValues();
gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
}
- gc = XCreateGC(DisplayHandle, hwnd.client_window, 0, ref gc_values);
+ gc = XCreateGC(DisplayHandle, hwnd.client_window, IntPtr.Zero, ref gc_values);
+
+ int src_x, src_y;
+ int dest_x, dest_y;
+ int width, height;
+
+ if (YAmount > 0) {
+ src_y = area.Y;
+ height = area.Height - YAmount;
+ dest_y = area.Y + YAmount;
+ }
+ else {
+ src_y = area.Y - YAmount;
+ height = area.Height + YAmount;
+ dest_y = area.Y;
+ }
+
+ if (XAmount > 0) {
+ src_x = area.X;
+ width = area.Width - XAmount;
+ dest_x = area.X + XAmount;
+ }
+ else {
+ src_x = area.X - XAmount;
+ width = area.Width + XAmount;
+ dest_x = area.X;
+ }
- XCopyArea(DisplayHandle, hwnd.client_window, hwnd.client_window, gc, area.X - XAmount, area.Y - YAmount, area.Width, area.Height, area.X, area.Y);
+ XCopyArea(DisplayHandle, hwnd.client_window, hwnd.client_window, gc, src_x, src_y, width, height, dest_x, dest_y);
// Generate an expose for the area exposed by the horizontal scroll
+ // We don't use AddExpose since we're
if (XAmount > 0) {
- hwnd.AddInvalidArea (area.X, area.Y, XAmount, area.Height);
+ AddExpose(hwnd, true, area.X, area.Y, XAmount, area.Height);
} else if (XAmount < 0) {
- hwnd.AddInvalidArea (XAmount + area.X + area.Width, area.Y, -XAmount, area.Height);
+ AddExpose(hwnd, true, XAmount + area.X + area.Width, area.Y, -XAmount, area.Height);
}
// Generate an expose for the area exposed by the vertical scroll
if (YAmount > 0) {
- hwnd.AddInvalidArea (area.X, area.Y, area.Width, YAmount);
+ AddExpose(hwnd, true, area.X, area.Y, area.Width, YAmount);
} else if (YAmount < 0) {
- hwnd.AddInvalidArea (area.X, YAmount + area.Y + area.Height, area.Width, -YAmount);
+ AddExpose(hwnd, true, area.X, YAmount + area.Y + area.Height, area.Width, -YAmount);
}
XFreeGC(DisplayHandle, gc);
-
- UpdateWindow(handle);
}
internal override void ScrollWindow(IntPtr handle, int XAmount, int YAmount, bool with_children) {
- Hwnd hwnd;
+ Hwnd hwnd;
+ Rectangle rect;
hwnd = Hwnd.GetObjectFromWindow(handle);
- ScrollWindow(handle, hwnd.ClientRect, XAmount, YAmount, with_children);
+ rect = hwnd.ClientRect;
+ rect.X = 0;
+ rect.Y = 0;
+ ScrollWindow(handle, rect, XAmount, YAmount, with_children);
}
internal override void SendAsyncMethod (AsyncMethodData method) {
- XEvent xevent = new XEvent ();
+ Hwnd hwnd;
+ XEvent xevent = new XEvent ();
+
+ hwnd = Hwnd.ObjectFromHandle(FosterParent);
xevent.type = XEventName.ClientMessage;
xevent.ClientMessageEvent.display = DisplayHandle;
xevent.ClientMessageEvent.format = 32;
xevent.ClientMessageEvent.ptr1 = (IntPtr) GCHandle.Alloc (method);
- MessageQueue.EnqueueLocked (xevent);
+ hwnd.Queue.EnqueueLocked (xevent);
WakeupMain ();
}
hwnd = Hwnd.ObjectFromHandle(handle);
hwnd.border_style = border_style;
-
- XMoveResizeWindow(DisplayHandle, hwnd.client_window, hwnd.ClientRect.X, hwnd.ClientRect.Y, hwnd.ClientRect.Width, hwnd.ClientRect.Height);
-
- InvalidateWholeWindow(handle);
+ RequestNCRecalc(handle);
}
internal override void SetCaretPos(IntPtr handle, int x, int y) {
Caret.X = x;
Caret.Y = y;
- if (Caret.Visible == 1) {
+ if (Caret.Visible == true) {
ShowCaret();
Caret.Timer.Start();
}
}
}
+ internal override void SetClipRegion(IntPtr handle, Region region) {
+ Hwnd hwnd;
+
+ hwnd = Hwnd.ObjectFromHandle(handle);
+ if (hwnd == null) {
+ return;
+ }
+
+ hwnd.UserClip = region;
+ Invalidate(handle, new Rectangle(0, 0, hwnd.Width, hwnd.Height), false);
+ }
+
internal override void SetCursor(IntPtr handle, IntPtr cursor) {
Hwnd hwnd;
hwnd = Hwnd.ObjectFromHandle(handle);
+ if (hwnd.client_window == FocusWindow) {
+ return;
+ }
+
+ SendMessage(hwnd.client_window, Msg.WM_SETFOCUS, FocusWindow, IntPtr.Zero);
if (FocusWindow != IntPtr.Zero) {
- PostMessage(FocusWindow, Msg.WM_KILLFOCUS, hwnd.client_window, IntPtr.Zero);
+ SendMessage(FocusWindow, Msg.WM_KILLFOCUS, hwnd.client_window, IntPtr.Zero);
}
- PostMessage(hwnd.client_window, Msg.WM_SETFOCUS, FocusWindow, IntPtr.Zero);
FocusWindow = hwnd.client_window;
//XSetInputFocus(DisplayHandle, Hwnd.ObjectFromHandle(handle).client_window, RevertTo.None, IntPtr.Zero);
hwnd = Hwnd.ObjectFromHandle(handle);
hwnd.menu = menu;
- // FIXME - do we need to trigger some resize?
+ RequestNCRecalc(handle);
}
internal override void SetModal(IntPtr handle, bool Modal) {
hwnd.parent = Hwnd.ObjectFromHandle(parent);
lock (XlibLock) {
- #if DriverDebug
- Console.WriteLine("Parent for window {0:X} / {1:X} = {2:X} (Handle:{3:X})", hwnd.ClientWindow.ToInt32(), hwnd.WholeWindow.ToInt32(), hwnd.parent != null ? hwnd.parent.Handle.ToInt32() : 0, parent.ToInt32());
+ #if DriverDebug || DriverDebugParent
+ Console.WriteLine("Parent for window {0} = {1}", XplatUI.Window(hwnd.Handle), XplatUI.Window(hwnd.parent != null ? hwnd.parent.Handle : IntPtr.Zero));
#endif
XReparentWindow(DisplayHandle, hwnd.whole_window, hwnd.parent.client_window, hwnd.x, hwnd.y);
}
if (hwnd_owner != null) {
XSetTransientForHint(DisplayHandle, hwnd.whole_window, hwnd_owner.whole_window);
} else {
- XSetTransientForHint(DisplayHandle, hwnd.whole_window, FosterParent);
+ XSetTransientForHint(DisplayHandle, hwnd.whole_window, RootWindow);
}
}
} else {
lock (XlibLock) {
- XDeleteProperty(DisplayHandle, hwnd.whole_window, (int)Atom.XA_WM_TRANSIENT_FOR);
+ XDeleteProperty(DisplayHandle, hwnd.whole_window, (IntPtr)Atom.XA_WM_TRANSIENT_FOR);
}
}
return true;
lock (XlibLock) {
if (visible) {
- XMapWindow(DisplayHandle, hwnd.whole_window);
- XMapWindow(DisplayHandle, hwnd.client_window);
+ if (Control.FromHandle(handle) is Form) {
+ FormWindowState s;
+
+ s = ((Form)Control.FromHandle(handle)).WindowState;
+
+ MapWindow(hwnd, WindowType.Both);
+
+ switch(s) {
+ case FormWindowState.Minimized: SetWindowState(handle, FormWindowState.Minimized); break;
+ case FormWindowState.Maximized: SetWindowState(handle, FormWindowState.Maximized); break;
+ }
+
+ } else {
+ MapWindow(hwnd, WindowType.Both);
+ }
+ SendMessage(handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
} else {
- XUnmapWindow(DisplayHandle, hwnd.whole_window);
+ UnmapWindow(hwnd, WindowType.Whole);
}
}
return true;
}
+ internal override void SetWindowMinMax(IntPtr handle, Rectangle maximized, Size min, Size max) {
+ Hwnd hwnd;
+ XSizeHints hints;
+
+ hwnd = Hwnd.ObjectFromHandle(handle);
+ if (hwnd == null) {
+ return;
+ }
+
+ hints = new XSizeHints();
+ if ((min != Size.Empty) && (min.Width > 0) && (min.Height > 0)) {
+ hints.flags = (IntPtr)((int)hints.flags | (int)XSizeHintsFlags.PMinSize);
+ hints.min_width = min.Width;
+ hints.min_height = min.Height;
+ }
+
+ if ((max != Size.Empty) && (max.Width > 0) && (max.Height > 0)) {
+ hints.flags = (IntPtr)((int)hints.flags | (int)XSizeHintsFlags.PMaxSize);
+ hints.max_width = max.Width;
+ hints.max_height = max.Height;
+ }
+
+ if (hints.flags != IntPtr.Zero) {
+ XSetWMNormalHints(DisplayHandle, hwnd.whole_window, ref hints);
+ }
+
+ if ((maximized != Rectangle.Empty) && (maximized.Width > 0) && (maximized.Height > 0)) {
+ hints.flags = (IntPtr)XSizeHintsFlags.PPosition;
+ hints.x = maximized.X;
+ hints.y = maximized.Y;
+ hints.width = maximized.Width;
+ hints.height = maximized.Height;
+
+ // Metacity does not seem to follow this constraint for maximized (zoomed) windows
+ XSetZoomHints(DisplayHandle, hwnd.whole_window, ref hints);
+ }
+ }
+
+
internal override void SetWindowPos(IntPtr handle, int x, int y, int width, int height) {
Hwnd hwnd;
- Rectangle client_rect;
hwnd = Hwnd.ObjectFromHandle(handle);
// X requires a sanity check for width & height; otherwise it dies
if (hwnd.zero_sized && width > 0 && height > 0) {
if (hwnd.visible) {
- XMapWindow(DisplayHandle, hwnd.whole_window);
+ MapWindow(hwnd, WindowType.Whole);
}
hwnd.zero_sized = false;
}
- if (width < 1) {
+ if ((width < 1) || (height < 1)) {
hwnd.zero_sized = true;
- XUnmapWindow(DisplayHandle, hwnd.whole_window);
+ UnmapWindow(hwnd, WindowType.Whole);
}
- if (height < 1) {
- hwnd.zero_sized = true;
- XUnmapWindow(DisplayHandle, hwnd.whole_window);
- }
-
- client_rect = Hwnd.GetClientRectangle(hwnd.border_style, hwnd.menu, hwnd.title_style, hwnd.caption_height, hwnd.tool_caption_height, width, height);
-
// Save a server roundtrip (and prevent a feedback loop)
if ((hwnd.x == x) && (hwnd.y == y) &&
- (hwnd.width == width) && (hwnd.height == height) &&
- (hwnd.ClientRect == client_rect)) {
+ (hwnd.width == width) && (hwnd.height == height)) {
return;
}
if (!hwnd.zero_sized) {
+
+ if (hwnd.fixed_size) {
+ SetWindowMinMax(handle, Rectangle.Empty, new Size(width, height), new Size(width, height));
+ }
+
lock (XlibLock) {
XMoveResizeWindow(DisplayHandle, hwnd.whole_window, x, y, width, height);
- XMoveResizeWindow(DisplayHandle, hwnd.client_window, client_rect.X, client_rect.Y, client_rect.Width, client_rect.Height);
+ PerformNCCalc(hwnd);
}
}
hwnd = Hwnd.ObjectFromHandle(handle);
- current_state = GetWindowState(handle);
+ try {
+ current_state = GetWindowState(handle);
+ }
+ catch (NotSupportedException) {
+ current_state = (FormWindowState)(-1);
+ }
if (current_state == state) {
return;
case FormWindowState.Normal: {
lock (XlibLock) {
if (current_state == FormWindowState.Minimized) {
- XMapWindow(DisplayHandle, hwnd.whole_window);
- XMapWindow(DisplayHandle, hwnd.client_window);
+ MapWindow(hwnd, WindowType.Both);
} else if (current_state == FormWindowState.Maximized) {
- SendNetWMMessage(hwnd.whole_window, (IntPtr)(uint)NetAtoms[(int)NA._NET_WM_STATE], (IntPtr)2 /* toggle */, (IntPtr)NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_HORZ], (IntPtr)NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_VERT]);
+ SendNetWMMessage(hwnd.whole_window, NetAtoms[(int)NA._NET_WM_STATE], (IntPtr)2 /* toggle */, NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_HORZ], NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_VERT]);
}
}
Activate(handle);
case FormWindowState.Minimized: {
lock (XlibLock) {
if (current_state == FormWindowState.Maximized) {
- SendNetWMMessage(hwnd.whole_window, (IntPtr)NetAtoms[(int)NA._NET_WM_STATE], (IntPtr)2 /* toggle */, (IntPtr)NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_HORZ], (IntPtr)NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_VERT]);
+ SendNetWMMessage(hwnd.whole_window, NetAtoms[(int)NA._NET_WM_STATE], (IntPtr)2 /* toggle */, NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_HORZ], NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_VERT]);
}
- XIconifyWindow(DisplayHandle, hwnd.whole_window, 0);
+ XIconifyWindow(DisplayHandle, hwnd.whole_window, ScreenNo);
}
return;
}
case FormWindowState.Maximized: {
lock (XlibLock) {
if (current_state == FormWindowState.Minimized) {
- XMapWindow(DisplayHandle, hwnd.whole_window);
- XMapWindow(DisplayHandle, hwnd.client_window);
+ MapWindow(hwnd, WindowType.Both);
}
- SendNetWMMessage(hwnd.whole_window, (IntPtr)NetAtoms[(int)NA._NET_WM_STATE], (IntPtr)1 /* Add */, (IntPtr)NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_HORZ], (IntPtr)NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_VERT]);
+ SendNetWMMessage(hwnd.whole_window, NetAtoms[(int)NA._NET_WM_STATE], (IntPtr)1 /* Add */, NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_HORZ], NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_VERT]);
}
Activate(handle);
return;
}
internal override void SetWindowTransparency(IntPtr handle, double transparency, Color key) {
+ Hwnd hwnd;
+ IntPtr opacity;
+
+ hwnd = Hwnd.ObjectFromHandle(handle);
+
+ if (hwnd == null) {
+ return;
+ }
+
+ hwnd.opacity = (uint)(0xffffffff * transparency);
+ opacity = (IntPtr)((int)hwnd.opacity);
+
+ if (hwnd.reparented) {
+ XChangeProperty(DisplayHandle, XGetParent(hwnd.whole_window), NetAtoms[(int)NA._NET_WM_WINDOW_OPACITY], (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, ref opacity, 1);
+ }
}
internal override bool SetZOrder(IntPtr handle, IntPtr after_handle, bool top, bool bottom) {
; // FIXME - X11 doesn't 'hide' the cursor. we could create an empty cursor
}
+ internal override object StartLoop(Thread thread) {
+ return (Object) ThreadQueue(thread);
+ }
+
+ internal override bool SupportsTransparency() {
+ // We need to check if the x compositing manager is running
+ return true;
+ }
+
internal override bool SystrayAdd(IntPtr handle, string tip, Icon icon, out ToolTip tt) {
GetSystrayManagerWindow();
if (SystrayMgrWindow != IntPtr.Zero) {
- uint[] atoms;
XSizeHints size_hints;
Hwnd hwnd;
Console.WriteLine("Adding Systray Whole:{0:X}, Client:{1:X}", hwnd.whole_window.ToInt32(), hwnd.client_window.ToInt32());
#endif
- XUnmapWindow(DisplayHandle, hwnd.whole_window);
- XUnmapWindow(DisplayHandle, hwnd.client_window);
+ UnmapWindow(hwnd, WindowType.Whole);
// Oh boy.
XDestroyWindow(DisplayHandle, hwnd.client_window);
size_hints.base_height = icon.Height;
XSetWMNormalHints(DisplayHandle, hwnd.whole_window, ref size_hints);
- atoms = new uint[2];
- atoms[0] = 1; // Version 1
- atoms[1] = 0; // We're not mapped
+ int[] atoms = new int[2];
+ atoms [0] = 1; // Version 1
+ atoms [1] = 0; // We're not mapped
// This line cost me 3 days...
XChangeProperty(DisplayHandle, hwnd.whole_window, NetAtoms[(int)NA._XEMBED_INFO], NetAtoms[(int)NA._XEMBED_INFO], 32, PropertyMode.Replace, atoms, 2);
// Make sure the window exists
XSync(DisplayHandle, hwnd.whole_window);
- SendNetClientMessage(SystrayMgrWindow, (IntPtr)NetAtoms[(int)NA._NET_SYSTEM_TRAY_OPCODE], IntPtr.Zero, (IntPtr)SystrayRequest.SYSTEM_TRAY_REQUEST_DOCK, hwnd.whole_window);
+ SendNetClientMessage(SystrayMgrWindow, NetAtoms[(int)NA._NET_SYSTEM_TRAY_OPCODE], IntPtr.Zero, (IntPtr)SystrayRequest.SYSTEM_TRAY_REQUEST_DOCK, hwnd.whole_window);
return true;
}
tt = null;
hwnd = Hwnd.ObjectFromHandle(handle);
- XUnmapWindow(DisplayHandle, hwnd.whole_window);
+ UnmapWindow(hwnd, WindowType.Whole);
SetParent(hwnd.whole_window, FosterParent);
// The caller can now re-dock it later...
}
internal override void UpdateWindow(IntPtr handle) {
- XEvent xevent;
Hwnd hwnd;
hwnd = Hwnd.ObjectFromHandle(handle);
-// if (!hwnd.visible || hwnd.expose_pending) {
- if (!hwnd.visible || hwnd.destroy_pending) {
+ if (!hwnd.visible || !hwnd.expose_pending) {
return;
}
SendMessage(handle, Msg.WM_PAINT, IntPtr.Zero, IntPtr.Zero);
-#if not
-#if true
- xevent = new XEvent();
- xevent.type = XEventName.Expose;
- xevent.ExposeEvent.display = DisplayHandle;
- xevent.ExposeEvent.window = hwnd.client_window;
-
- MessageQueue.Enqueue(xevent);
- hwnd.expose_pending = true;
-#else
- // This would force an immediate paint (SendMessage, instead of PostMessage)
- if (!hwnd.visible) {
- return;
- }
+ hwnd.Queue.Paint.Remove(hwnd);
+ }
- if (!hwnd.expose_pending) {
- xevent = new XEvent();
- xevent.type = XEventName.Expose;
- xevent.ExposeEvent.display = DisplayHandle;
- xevent.ExposeEvent.window = hwnd.client_window;
+ private bool WindowIsMapped(IntPtr handle) {
+ XWindowAttributes attributes;
- MessageQueue.Enqueue(xevent);
- hwnd.expose_pending = true;
+ attributes = new XWindowAttributes();
+ XGetWindowAttributes(DisplayHandle, handle, ref attributes);
+ if (attributes.map_state == MapState.IsUnmapped) {
+ return false;
}
- NativeWindow.WndProc(hwnd.client_window, Msg.WM_PAINT, IntPtr.Zero, IntPtr.Zero);
-#endif
-#endif
+ return true;
}
+
#endregion // Public Static Methods
#region Events
internal extern static IntPtr XSynchronize(IntPtr display, bool onoff);
[DllImport ("libX11", 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, SetWindowValuemask valuemask, ref XSetWindowAttributes attributes);
+ 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, UIntPtr valuemask, ref XSetWindowAttributes attributes);
[DllImport ("libX11", 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);
+ internal extern static IntPtr XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, UIntPtr border, UIntPtr background);
[DllImport ("libX11", EntryPoint="XMapWindow")]
internal extern static int XMapWindow(IntPtr display, IntPtr window);
[DllImport ("libX11", EntryPoint="XUnmapWindow")]
internal extern static int XConnectionNumber (IntPtr diplay);
[DllImport ("libX11")]
internal extern static int XPending (IntPtr diplay);
- [DllImport ("libX11")]
- internal extern static bool XCheckWindowEvent (IntPtr display, IntPtr window, EventMask mask, ref XEvent xevent);
- [DllImport ("libX11")]
- internal extern static bool XCheckMaskEvent (IntPtr display, EventMask mask, ref XEvent xevent);
[DllImport ("libX11", EntryPoint="XSelectInput")]
- internal extern static IntPtr XSelectInput(IntPtr display, IntPtr window, EventMask mask);
+ internal extern static IntPtr XSelectInput(IntPtr display, IntPtr window, IntPtr mask);
[DllImport ("libX11", EntryPoint="XDestroyWindow")]
internal extern static int XDestroyWindow(IntPtr display, IntPtr window);
internal extern static int XFetchName(IntPtr display, IntPtr window, ref IntPtr window_name);
[DllImport ("libX11", EntryPoint="XSendEvent")]
- internal extern static int XSendEvent(IntPtr display, IntPtr window, bool propagate, EventMask event_mask, ref XEvent send_event);
+ internal extern static int XSendEvent(IntPtr display, IntPtr window, bool propagate, IntPtr event_mask, ref XEvent send_event);
[DllImport ("libX11", EntryPoint="XQueryTree")]
internal extern static int XQueryTree(IntPtr display, IntPtr window, out IntPtr root_return, out IntPtr parent_return, out IntPtr children_return, out int nchildren_return);
internal extern static uint XConfigureWindow(IntPtr display, IntPtr window, ChangeWindowFlags value_mask, ref XWindowChanges values);
[DllImport ("libX11", EntryPoint="XInternAtom")]
- internal extern static int XInternAtom(IntPtr display, string atom_name, bool only_if_exists);
+ internal extern static IntPtr XInternAtom(IntPtr display, string atom_name, bool only_if_exists);
[DllImport ("libX11", EntryPoint="XSetWMProtocols")]
- internal extern static int XSetWMProtocols(IntPtr display, IntPtr window, uint[] protocols, int count);
+ internal extern static int XSetWMProtocols(IntPtr display, IntPtr window, IntPtr[] protocols, int count);
[DllImport ("libX11", 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);
+ internal extern static int XGrabPointer(IntPtr display, IntPtr window, bool owner_events, EventMask event_mask, GrabMode pointer_mode, GrabMode keyboard_mode, IntPtr confine_to, IntPtr cursor, IntPtr timestamp);
[DllImport ("libX11", EntryPoint="XUngrabPointer")]
- internal extern static int XUngrabPointer(IntPtr display, uint timestamp);
+ internal extern static int XUngrabPointer(IntPtr display, IntPtr timestamp);
[DllImport ("libX11", 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", EntryPoint="XDefaultDepth")]
internal extern static uint XDefaultDepth(IntPtr display, int screen_number);
+ [DllImport ("libX11", EntryPoint="XDefaultScreen")]
+ internal extern static int XDefaultScreen(IntPtr display);
+
[DllImport ("libX11", EntryPoint="XDefaultColormap")]
internal extern static IntPtr XDefaultColormap(IntPtr display, int screen_number);
internal extern static int XSetTransientForHint(IntPtr display, IntPtr window, IntPtr prop_window);
[DllImport ("libX11", EntryPoint="XChangeProperty")]
- internal extern static int XChangeProperty(IntPtr display, IntPtr window, int property, int type, int format, PropertyMode mode, ref MotifWmHints data, int nelements);
+ internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref MotifWmHints data, int nelements);
+
+ [DllImport ("libX11", EntryPoint="XChangeProperty")]
+ internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref uint value, int nelements);
+
+ [DllImport ("libX11", EntryPoint="XChangeProperty")]
+ internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref IntPtr value, int nelements);
[DllImport ("libX11", EntryPoint="XChangeProperty")]
- internal extern static int XChangeProperty(IntPtr display, IntPtr window, int property, Atom format, int type, PropertyMode mode, uint[] atoms, int nelements);
+ internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, uint[] data, int nelements);
[DllImport ("libX11", EntryPoint="XChangeProperty")]
- internal extern static int XChangeProperty(IntPtr display, IntPtr window, int property, int format, int type, PropertyMode mode, uint[] atoms, int nelements);
+ internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, int[] data, int nelements);
[DllImport ("libX11", EntryPoint="XChangeProperty")]
- internal extern static int XChangeProperty(IntPtr display, IntPtr window, int property, int format, int type, PropertyMode mode, IntPtr atoms, int nelements);
+ internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr[] data, int nelements);
[DllImport ("libX11", EntryPoint="XChangeProperty")]
- internal extern static int XChangeProperty(IntPtr display, IntPtr window, int property, Atom format, int type, PropertyMode mode, IntPtr atoms, int nelements);
+ internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr atoms, int nelements);
[DllImport ("libX11", EntryPoint="XChangeProperty", CharSet=CharSet.Ansi)]
- internal extern static int XChangeProperty(IntPtr display, IntPtr window, int property, int type, int format, PropertyMode mode, string text, int text_length);
+ internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, string text, int text_length);
[DllImport ("libX11", EntryPoint="XDeleteProperty")]
- internal extern static int XDeleteProperty(IntPtr display, IntPtr window, int property);
+ internal extern static int XDeleteProperty(IntPtr display, IntPtr window, IntPtr property);
[DllImport ("gdiplus", EntryPoint="GetFontMetrics")]
internal extern static bool GetFontMetrics(IntPtr graphicsObject, IntPtr nativeObject, out int ascent, out int descent);
// Drawing
[DllImport ("libX11", EntryPoint="XCreateGC")]
- internal extern static IntPtr XCreateGC(IntPtr display, IntPtr window, GCFunction valuemask, ref XGCValues values);
+ internal extern static IntPtr XCreateGC(IntPtr display, IntPtr window, IntPtr valuemask, ref XGCValues values);
[DllImport ("libX11", EntryPoint="XFreeGC")]
internal extern static int XFreeGC(IntPtr display, IntPtr gc);
[DllImport ("libX11", EntryPoint="XCopyArea")]
internal extern static int XCopyArea(IntPtr display, IntPtr src, IntPtr dest, IntPtr gc, int src_x, int src_y, int width, int height, int dest_x, int dest_y);
- [DllImport ("libX11", EntryPoint="XGetAtomName")]
- internal extern static string XGetAtomName(IntPtr display, int atom);
-
[DllImport ("libX11", EntryPoint="XGetWindowProperty")]
- internal extern static int XGetWindowProperty(IntPtr display, IntPtr window, int atom, int long_offset, int long_length, bool delete, Atom req_type, out Atom actual_type, out int actual_format, out int nitems, out int bytes_after, ref IntPtr prop);
+ internal extern static int XGetWindowProperty(IntPtr display, IntPtr window, IntPtr atom, IntPtr long_offset, IntPtr long_length, bool delete, IntPtr req_type, out IntPtr actual_type, out int actual_format, out IntPtr nitems, out IntPtr bytes_after, ref IntPtr prop);
[DllImport ("libX11", EntryPoint="XSetInputFocus")]
internal extern static int XSetInputFocus(IntPtr display, IntPtr window, RevertTo revert_to, IntPtr time);
[DllImport ("libX11", EntryPoint="XSetWMNormalHints")]
internal extern static void XSetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints);
+ [DllImport ("libX11", EntryPoint="XSetZoomHints")]
+ internal extern static void XSetZoomHints(IntPtr display, IntPtr window, ref XSizeHints hints);
+
[DllImport ("libX11", EntryPoint="XSetWMHints")]
internal extern static void XSetWMHints(IntPtr display, IntPtr window, ref XWMHints wmhints);
internal extern static int XInitThreads();
[DllImport ("libX11", EntryPoint="XConvertSelection")]
- internal extern static int XConvertSelection(IntPtr display, int selection, int target, int property, IntPtr requestor, IntPtr time);
+ internal extern static int XConvertSelection(IntPtr display, IntPtr selection, IntPtr target, IntPtr property, IntPtr requestor, IntPtr time);
[DllImport ("libX11", EntryPoint="XGetSelectionOwner")]
- internal extern static IntPtr XGetSelectionOwner(IntPtr display, int selection);
+ internal extern static IntPtr XGetSelectionOwner(IntPtr display, IntPtr selection);
[DllImport ("libX11", EntryPoint="XSetSelectionOwner")]
- internal extern static int XSetSelectionOwner(IntPtr display, int selection, IntPtr owner, IntPtr time);
+ internal extern static int XSetSelectionOwner(IntPtr display, IntPtr selection, IntPtr owner, IntPtr time);
[DllImport ("libX11", EntryPoint="XSetPlaneMask")]
- internal extern static int XSetPlaneMask(IntPtr display, IntPtr gc, uint mask);
+ internal extern static int XSetPlaneMask(IntPtr display, IntPtr gc, IntPtr mask);
[DllImport ("libX11", EntryPoint="XSetForeground")]
- internal extern static int XSetForeground(IntPtr display, IntPtr gc, uint foreground);
+ internal extern static int XSetForeground(IntPtr display, IntPtr gc, UIntPtr foreground);
[DllImport ("libX11", EntryPoint="XSetBackground")]
- internal extern static int XSetBackground(IntPtr display, IntPtr gc, uint background);
+ internal extern static int XSetBackground(IntPtr display, IntPtr gc, UIntPtr background);
[DllImport ("libX11", EntryPoint="XBell")]
internal extern static int XBell(IntPtr display, int percent);
+
+ [DllImport ("libX11", EntryPoint="XChangeActivePointerGrab")]
+ internal extern static int XChangeActivePointerGrab (IntPtr display, EventMask event_mask, IntPtr cursor, IntPtr time);
+
+ [DllImport ("libX11", EntryPoint="XFilterEvent")]
+ internal extern static bool XFilterEvent(ref XEvent xevent, IntPtr window);
#endregion
}
}