#undef DriverDebugCreate
#undef DriverDebugDestroy
#undef DriverDebugThreads
+#undef DriverDebugXEmbed
using System;
using System.ComponentModel;
private static Hashtable MessageQueues; // Holds our thread-specific XEventQueues
#if __MonoCS__ //
private static Pollfd[] pollfds; // For watching the X11 socket
+ private static bool wake_waiting;
+ private static object wake_waiting_lock = new object ();
#endif //
private static X11Keyboard Keyboard; //
private static X11Dnd Dnd;
private static IntPtr WM_PROTOCOLS;
private static IntPtr WM_DELETE_WINDOW;
private static IntPtr WM_TAKE_FOCUS;
- private static IntPtr _NET_SUPPORTED;
- private static IntPtr _NET_CLIENT_LIST;
- private static IntPtr _NET_NUMBER_OF_DESKTOPS;
- private static IntPtr _NET_DESKTOP_GEOMETRY;
- private static IntPtr _NET_DESKTOP_VIEWPORT;
+ //private static IntPtr _NET_SUPPORTED;
+ //private static IntPtr _NET_CLIENT_LIST;
+ //private static IntPtr _NET_NUMBER_OF_DESKTOPS;
+ //private static IntPtr _NET_DESKTOP_GEOMETRY;
+ //private static IntPtr _NET_DESKTOP_VIEWPORT;
private static IntPtr _NET_CURRENT_DESKTOP;
- private static IntPtr _NET_DESKTOP_NAMES;
+ //private static IntPtr _NET_DESKTOP_NAMES;
private static IntPtr _NET_ACTIVE_WINDOW;
private static IntPtr _NET_WORKAREA;
- private static IntPtr _NET_SUPPORTING_WM_CHECK;
- private static IntPtr _NET_VIRTUAL_ROOTS;
- private static IntPtr _NET_DESKTOP_LAYOUT;
- private static IntPtr _NET_SHOWING_DESKTOP;
- private static IntPtr _NET_CLOSE_WINDOW;
- private static IntPtr _NET_MOVERESIZE_WINDOW;
- private static IntPtr _NET_WM_MOVERESIZE;
- private static IntPtr _NET_RESTACK_WINDOW;
- private static IntPtr _NET_REQUEST_FRAME_EXTENTS;
+ //private static IntPtr _NET_SUPPORTING_WM_CHECK;
+ //private static IntPtr _NET_VIRTUAL_ROOTS;
+ //private static IntPtr _NET_DESKTOP_LAYOUT;
+ //private static IntPtr _NET_SHOWING_DESKTOP;
+ //private static IntPtr _NET_CLOSE_WINDOW;
+ //private static IntPtr _NET_MOVERESIZE_WINDOW;
+ //private static IntPtr _NET_WM_MOVERESIZE;
+ //private static IntPtr _NET_RESTACK_WINDOW;
+ //private static IntPtr _NET_REQUEST_FRAME_EXTENTS;
private static IntPtr _NET_WM_NAME;
- private static IntPtr _NET_WM_VISIBLE_NAME;
- private static IntPtr _NET_WM_ICON_NAME;
- private static IntPtr _NET_WM_VISIBLE_ICON_NAME;
- private static IntPtr _NET_WM_DESKTOP;
+ //private static IntPtr _NET_WM_VISIBLE_NAME;
+ //private static IntPtr _NET_WM_ICON_NAME;
+ //private static IntPtr _NET_WM_VISIBLE_ICON_NAME;
+ //private static IntPtr _NET_WM_DESKTOP;
private static IntPtr _NET_WM_WINDOW_TYPE;
private static IntPtr _NET_WM_STATE;
- private static IntPtr _NET_WM_ALLOWED_ACTIONS;
- private static IntPtr _NET_WM_STRUT;
- private static IntPtr _NET_WM_STRUT_PARTIAL;
- private static IntPtr _NET_WM_ICON_GEOMETRY;
+ //private static IntPtr _NET_WM_ALLOWED_ACTIONS;
+ //private static IntPtr _NET_WM_STRUT;
+ //private static IntPtr _NET_WM_STRUT_PARTIAL;
+ //private static IntPtr _NET_WM_ICON_GEOMETRY;
private static IntPtr _NET_WM_ICON;
- private static IntPtr _NET_WM_PID;
- private static IntPtr _NET_WM_HANDLED_ICONS;
+ //private static IntPtr _NET_WM_PID;
+ //private static IntPtr _NET_WM_HANDLED_ICONS;
private static IntPtr _NET_WM_USER_TIME;
private static IntPtr _NET_FRAME_EXTENTS;
- private static IntPtr _NET_WM_PING;
- private static IntPtr _NET_WM_SYNC_REQUEST;
+ //private static IntPtr _NET_WM_PING;
+ //private static IntPtr _NET_WM_SYNC_REQUEST;
private static IntPtr _NET_SYSTEM_TRAY_S;
- private static IntPtr _NET_SYSTEM_TRAY_ORIENTATION;
+ //private static IntPtr _NET_SYSTEM_TRAY_ORIENTATION;
private static IntPtr _NET_SYSTEM_TRAY_OPCODE;
private static IntPtr _NET_WM_STATE_MAXIMIZED_HORZ;
private static IntPtr _NET_WM_STATE_MAXIMIZED_VERT;
private static IntPtr _XEMBED;
private static IntPtr _XEMBED_INFO;
private static IntPtr _MOTIF_WM_HINTS;
- private static IntPtr _NET_WM_STATE_NO_TASKBAR;
- private static IntPtr _NET_WM_STATE_ABOVE;
- private static IntPtr _NET_WM_STATE_MODAL;
+ private static IntPtr _NET_WM_STATE_SKIP_TASKBAR;
+ //private static IntPtr _NET_WM_STATE_ABOVE;
+ //private static IntPtr _NET_WM_STATE_MODAL;
private static IntPtr _NET_WM_STATE_HIDDEN;
private static IntPtr _NET_WM_CONTEXT_HELP;
private static IntPtr _NET_WM_WINDOW_OPACITY;
- private static IntPtr _NET_WM_WINDOW_TYPE_DESKTOP;
- private static IntPtr _NET_WM_WINDOW_TYPE_DOCK;
- private static IntPtr _NET_WM_WINDOW_TYPE_TOOLBAR;
- private static IntPtr _NET_WM_WINDOW_TYPE_MENU;
+ //private static IntPtr _NET_WM_WINDOW_TYPE_DESKTOP;
+ //private static IntPtr _NET_WM_WINDOW_TYPE_DOCK;
+ //private static IntPtr _NET_WM_WINDOW_TYPE_TOOLBAR;
+ //private static IntPtr _NET_WM_WINDOW_TYPE_MENU;
private static IntPtr _NET_WM_WINDOW_TYPE_UTILITY;
- private static IntPtr _NET_WM_WINDOW_TYPE_SPLASH;
- private static IntPtr _NET_WM_WINDOW_TYPE_DIALOG;
+ //private static IntPtr _NET_WM_WINDOW_TYPE_SPLASH;
+ //private static IntPtr _NET_WM_WINDOW_TYPE_DIALOG;
private static IntPtr _NET_WM_WINDOW_TYPE_NORMAL;
private static IntPtr CLIPBOARD;
private static IntPtr PRIMARY;
- private static IntPtr DIB;
+ //private static IntPtr DIB;
private static IntPtr OEMTEXT;
private static IntPtr UNICODETEXT;
private static IntPtr TARGETS;
private static GrabStruct Grab; //
// State
- private static Point MousePosition; // Last position of mouse, in screen coords
+ Point mouse_position; // Last position of mouse, in screen coords
internal static MouseButtons MouseState; // Last state of mouse buttons
// 'Constants'
private static int DoubleClickInterval; // msec; max interval between clicks to count as double click
- const EventMask SelectInputMask = EventMask.ButtonPressMask |
- EventMask.ButtonReleaseMask |
- EventMask.KeyPressMask |
- EventMask.KeyReleaseMask |
- EventMask.EnterWindowMask |
- EventMask.LeaveWindowMask |
- EventMask.ExposureMask |
- EventMask.FocusChangeMask |
- EventMask.PointerMotionMask |
- EventMask.VisibilityChangeMask |
- EventMask.SubstructureNotifyMask |
- EventMask.StructureNotifyMask;
+ const EventMask SelectInputMask = (EventMask.ButtonPressMask |
+ EventMask.ButtonReleaseMask |
+ EventMask.KeyPressMask |
+ EventMask.KeyReleaseMask |
+ EventMask.EnterWindowMask |
+ EventMask.LeaveWindowMask |
+ EventMask.ExposureMask |
+ EventMask.FocusChangeMask |
+ EventMask.PointerMotionMask |
+ EventMask.SubstructureNotifyMask);
static readonly object lockobj = new object ();
ModalWindows = new Stack(3);
MouseState = MouseButtons.None;
- MousePosition = new Point(0, 0);
+ mouse_position = new Point(0, 0);
Caret.Timer = new Timer();
Caret.Timer.Interval = 500; // FIXME - where should this number come from?
throw new ArgumentNullException("Display", "Could not open display (X-Server required. Check you DISPLAY environment variable)");
}
}
-
- internal static void Where() {
- Console.WriteLine("Here: {0}\n", WhereString());
- }
-
- internal static string WhereString() {
- StackTrace stack;
- StackFrame frame;
- string newline;
- string unknown;
- StringBuilder sb;
- MethodBase method;
-
- newline = String.Format("{0}\t {1} ", Environment.NewLine, Locale.GetText("at"));
- unknown = Locale.GetText("<unknown method>");
- sb = new StringBuilder();
- stack = new StackTrace(true);
-
- for (int i = 0; i < stack.FrameCount; i++) {
- frame = stack.GetFrame(i);
- sb.Append(newline);
-
- method = frame.GetMethod();
- if (method != null) {
- #if not
- sb.AppendFormat(frame.ToString());
- #endif
- if (frame.GetFileLineNumber() != 0) {
- sb.AppendFormat("{0}.{1} () [{2}:{3}]", method.DeclaringType.FullName, method.Name, Path.GetFileName(frame.GetFileName()), frame.GetFileLineNumber());
- } else {
- sb.AppendFormat("{0}.{1} ()", method.DeclaringType.FullName, method.Name);
- }
- } else {
- sb.Append(unknown);
- }
- }
- return sb.ToString();
- }
#endregion // Internal Methods
#region Private Methods
}
private static void SetupAtoms() {
- WM_PROTOCOLS = XInternAtom(DisplayHandle, "WM_PROTOCOLS", false);
- WM_DELETE_WINDOW = XInternAtom(DisplayHandle, "WM_DELETE_WINDOW", false);
- WM_TAKE_FOCUS = XInternAtom(DisplayHandle, "WM_TAKE_FOCUS", false);
-
- _NET_SUPPORTED = XInternAtom(DisplayHandle, "_NET_SUPPORTED", false);
- _NET_CLIENT_LIST = XInternAtom(DisplayHandle, "_NET_CLIENT_LIST", false);
- _NET_NUMBER_OF_DESKTOPS = XInternAtom(DisplayHandle, "_NET_NUMBER_OF_DESKTOPS", false);
- _NET_DESKTOP_GEOMETRY = XInternAtom(DisplayHandle, "_NET_DESKTOP_GEOMETRY", false);
- _NET_DESKTOP_VIEWPORT = XInternAtom(DisplayHandle, "_NET_DESKTOP_VIEWPORT", false);
- _NET_CURRENT_DESKTOP = XInternAtom(DisplayHandle, "_NET_CURRENT_DESKTOP", false);
- _NET_DESKTOP_NAMES = XInternAtom(DisplayHandle, "_NET_DESKTOP_NAMES", false);
- _NET_ACTIVE_WINDOW = XInternAtom(DisplayHandle, "_NET_ACTIVE_WINDOW", false);
- _NET_WORKAREA = XInternAtom(DisplayHandle, "_NET_WORKAREA", false);
- _NET_SUPPORTING_WM_CHECK = XInternAtom(DisplayHandle, "_NET_SUPPORTING_WM_CHECK", false);
- _NET_VIRTUAL_ROOTS = XInternAtom(DisplayHandle, "_NET_VIRTUAL_ROOTS", false);
- _NET_DESKTOP_LAYOUT = XInternAtom(DisplayHandle, "_NET_DESKTOP_LAYOUT", false);
- _NET_SHOWING_DESKTOP = XInternAtom(DisplayHandle, "_NET_SHOWING_DESKTOP", false);
-
- _NET_CLOSE_WINDOW = XInternAtom(DisplayHandle, "_NET_CLOSE_WINDOW", false);
- _NET_MOVERESIZE_WINDOW = XInternAtom(DisplayHandle, "_NET_MOVERESIZE_WINDOW", false);
- _NET_WM_MOVERESIZE = XInternAtom(DisplayHandle, "_NET_WM_MOVERESIZE", false);
- _NET_RESTACK_WINDOW = XInternAtom(DisplayHandle, "_NET_RESTACK_WINDOW", false);
- _NET_REQUEST_FRAME_EXTENTS = XInternAtom(DisplayHandle, "_NET_REQUEST_FRAME_EXTENTS", false);
-
- _NET_WM_NAME = XInternAtom(DisplayHandle, "_NET_WM_NAME", false);
- _NET_WM_VISIBLE_NAME = XInternAtom(DisplayHandle, "_NET_WM_VISIBLE_NAME", false);
- _NET_WM_ICON_NAME = XInternAtom(DisplayHandle, "_NET_WM_ICON_NAME", false);
- _NET_WM_VISIBLE_ICON_NAME = XInternAtom(DisplayHandle, "_NET_WM_VISIBLE_ICON_NAME", false);
- _NET_WM_DESKTOP = XInternAtom(DisplayHandle, "_NET_WM_DESKTOP", false);
- _NET_WM_WINDOW_TYPE = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE", false);
- _NET_WM_STATE = XInternAtom(DisplayHandle, "_NET_WM_STATE", false);
- _NET_WM_ALLOWED_ACTIONS = XInternAtom(DisplayHandle, "_NET_WM_ALLOWED_ACTIONS", false);
- _NET_WM_STRUT = XInternAtom(DisplayHandle, "_NET_WM_STRUT", false);
- _NET_WM_STRUT_PARTIAL = XInternAtom(DisplayHandle, "_NET_WM_STRUT_PARTIAL", false);
- _NET_WM_ICON_GEOMETRY = XInternAtom(DisplayHandle, "_NET_WM_ICON_GEOMETRY", false);
- _NET_WM_ICON = XInternAtom(DisplayHandle, "_NET_WM_ICON", false);
- _NET_WM_PID = XInternAtom(DisplayHandle, "_NET_WM_PID", false);
- _NET_WM_HANDLED_ICONS = XInternAtom(DisplayHandle, "_NET_WM_HANDLED_ICONS", false);
- _NET_WM_USER_TIME = XInternAtom(DisplayHandle, "_NET_WM_USER_TIME", false);
- _NET_FRAME_EXTENTS = XInternAtom(DisplayHandle, "_NET_FRAME_EXTENTS", false);
-
- _NET_WM_PING = XInternAtom(DisplayHandle, "_NET_WM_PING", false);
- _NET_WM_SYNC_REQUEST = XInternAtom(DisplayHandle, "_NET_WM_SYNC_REQUEST", false);
-
- _NET_SYSTEM_TRAY_S = XInternAtom(DisplayHandle, "_NET_SYSTEM_TRAY_S" + ScreenNo.ToString(), false);
- _NET_SYSTEM_TRAY_OPCODE = XInternAtom(DisplayHandle, "_NET_SYSTEM_TRAY_OPCODE", false);
- _NET_SYSTEM_TRAY_ORIENTATION = XInternAtom(DisplayHandle, "_NET_SYSTEM_TRAY_ORIENTATION", false);
-
- _NET_WM_STATE_MAXIMIZED_HORZ = XInternAtom(DisplayHandle, "_NET_WM_STATE_MAXIMIZED_HORZ", false);
- _NET_WM_STATE_MAXIMIZED_VERT = XInternAtom(DisplayHandle, "_NET_WM_STATE_MAXIMIZED_VERT", false);
- _NET_WM_STATE_HIDDEN = XInternAtom(DisplayHandle, "_NET_WM_STATE_HIDDEN", false);
-
- _XEMBED = XInternAtom(DisplayHandle, "_XEMBED", false);
- _XEMBED_INFO = XInternAtom(DisplayHandle, "_XEMBED_INFO", false);
-
- _MOTIF_WM_HINTS = XInternAtom(DisplayHandle, "_MOTIF_WM_HINTS", false);
-
- _NET_WM_STATE_NO_TASKBAR = XInternAtom(DisplayHandle, "_NET_WM_STATE_NO_TASKBAR", false);
- _NET_WM_STATE_ABOVE = XInternAtom(DisplayHandle, "_NET_WM_STATE_ABOVE", false);
- _NET_WM_STATE_MODAL = XInternAtom(DisplayHandle, "_NET_WM_STATE_MODAL", false);
- _NET_WM_CONTEXT_HELP = XInternAtom(DisplayHandle, "_NET_WM_CONTEXT_HELP", false);
- _NET_WM_WINDOW_OPACITY = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_OPACITY", false);
-
- _NET_WM_WINDOW_TYPE_DESKTOP = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE_DESKTOP", false);
- _NET_WM_WINDOW_TYPE_DOCK = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE_DOCK", false);
- _NET_WM_WINDOW_TYPE_TOOLBAR = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE_TOOLBAR", false);
- _NET_WM_WINDOW_TYPE_MENU = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE_MENU", false);
- _NET_WM_WINDOW_TYPE_UTILITY = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE_UTILITY", false);
- _NET_WM_WINDOW_TYPE_DIALOG = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE_DIALOG", false);
- _NET_WM_WINDOW_TYPE_SPLASH = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE_SPLASH", false);
- _NET_WM_WINDOW_TYPE_NORMAL = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE_NORMAL", false);
-
- // Clipboard support
- CLIPBOARD = XInternAtom (DisplayHandle, "CLIPBOARD", false);
- PRIMARY = XInternAtom (DisplayHandle, "PRIMARY", false);
- DIB = (IntPtr)Atom.XA_PIXMAP;
- OEMTEXT = XInternAtom(DisplayHandle, "COMPOUND_TEXT", false);
- UNICODETEXT = XInternAtom(DisplayHandle, "UTF8_STRING", false);
- TARGETS = XInternAtom(DisplayHandle, "TARGETS", false);
-
- // Special Atoms
- AsyncAtom = XInternAtom(DisplayHandle, "_SWF_AsyncAtom", false);
- PostAtom = XInternAtom (DisplayHandle, "_SWF_PostMessageAtom", false);
- HoverState.Atom = XInternAtom(DisplayHandle, "_SWF_HoverAtom", false);
+ // make sure this array stays in sync with the statements below
+ string [] atom_names = new string[] {
+ "WM_PROTOCOLS",
+ "WM_DELETE_WINDOW",
+ "WM_TAKE_FOCUS",
+ //"_NET_SUPPORTED",
+ //"_NET_CLIENT_LIST",
+ //"_NET_NUMBER_OF_DESKTOPS",
+ //"_NET_DESKTOP_GEOMETRY",
+ //"_NET_DESKTOP_VIEWPORT",
+ "_NET_CURRENT_DESKTOP",
+ //"_NET_DESKTOP_NAMES",
+ "_NET_ACTIVE_WINDOW",
+ "_NET_WORKAREA",
+ //"_NET_SUPPORTING_WM_CHECK",
+ //"_NET_VIRTUAL_ROOTS",
+ //"_NET_DESKTOP_LAYOUT",
+ //"_NET_SHOWING_DESKTOP",
+ //"_NET_CLOSE_WINDOW",
+ //"_NET_MOVERESIZE_WINDOW",
+ //"_NET_WM_MOVERESIZE",
+ //"_NET_RESTACK_WINDOW",
+ //"_NET_REQUEST_FRAME_EXTENTS",
+ "_NET_WM_NAME",
+ //"_NET_WM_VISIBLE_NAME",
+ //"_NET_WM_ICON_NAME",
+ //"_NET_WM_VISIBLE_ICON_NAME",
+ //"_NET_WM_DESKTOP",
+ "_NET_WM_WINDOW_TYPE",
+ "_NET_WM_STATE",
+ //"_NET_WM_ALLOWED_ACTIONS",
+ //"_NET_WM_STRUT",
+ //"_NET_WM_STRUT_PARTIAL",
+ //"_NET_WM_ICON_GEOMETRY",
+ "_NET_WM_ICON",
+ //"_NET_WM_PID",
+ //"_NET_WM_HANDLED_ICONS",
+ "_NET_WM_USER_TIME",
+ "_NET_FRAME_EXTENTS",
+ //"_NET_WM_PING",
+ //"_NET_WM_SYNC_REQUEST",
+ "_NET_SYSTEM_TRAY_OPCODE",
+ //"_NET_SYSTEM_TRAY_ORIENTATION",
+ "_NET_WM_STATE_MAXIMIZED_HORZ",
+ "_NET_WM_STATE_MAXIMIZED_VERT",
+ "_NET_WM_STATE_HIDDEN",
+ "_XEMBED",
+ "_XEMBED_INFO",
+ "_MOTIF_WM_HINTS",
+ "_NET_WM_STATE_SKIP_TASKBAR",
+ //"_NET_WM_STATE_ABOVE",
+ //"_NET_WM_STATE_MODAL",
+ "_NET_WM_CONTEXT_HELP",
+ "_NET_WM_WINDOW_OPACITY",
+ //"_NET_WM_WINDOW_TYPE_DESKTOP",
+ //"_NET_WM_WINDOW_TYPE_DOCK",
+ //"_NET_WM_WINDOW_TYPE_TOOLBAR",
+ //"_NET_WM_WINDOW_TYPE_MENU",
+ "_NET_WM_WINDOW_TYPE_UTILITY",
+ //"_NET_WM_WINDOW_TYPE_DIALOG",
+ //"_NET_WM_WINDOW_TYPE_SPLASH",
+ "_NET_WM_WINDOW_TYPE_NORMAL",
+ "CLIPBOARD",
+ "PRIMARY",
+ "COMPOUND_TEXT",
+ "UTF8_STRING",
+ "TARGETS",
+ "_SWF_AsyncAtom",
+ "_SWF_PostMessageAtom",
+ "_SWF_HoverAtom" };
+
+ IntPtr[] atoms = new IntPtr [atom_names.Length];;
+
+ XInternAtoms (DisplayHandle, atom_names, atom_names.Length, false, atoms);
+
+ int off = 0;
+ WM_PROTOCOLS = atoms [off++];
+ WM_DELETE_WINDOW = atoms [off++];
+ WM_TAKE_FOCUS = atoms [off++];
+ //_NET_SUPPORTED = atoms [off++];
+ //_NET_CLIENT_LIST = atoms [off++];
+ //_NET_NUMBER_OF_DESKTOPS = atoms [off++];
+ //_NET_DESKTOP_GEOMETRY = atoms [off++];
+ //_NET_DESKTOP_VIEWPORT = atoms [off++];
+ _NET_CURRENT_DESKTOP = atoms [off++];
+ //_NET_DESKTOP_NAMES = atoms [off++];
+ _NET_ACTIVE_WINDOW = atoms [off++];
+ _NET_WORKAREA = atoms [off++];
+ //_NET_SUPPORTING_WM_CHECK = atoms [off++];
+ //_NET_VIRTUAL_ROOTS = atoms [off++];
+ //_NET_DESKTOP_LAYOUT = atoms [off++];
+ //_NET_SHOWING_DESKTOP = atoms [off++];
+ //_NET_CLOSE_WINDOW = atoms [off++];
+ //_NET_MOVERESIZE_WINDOW = atoms [off++];
+ //_NET_WM_MOVERESIZE = atoms [off++];
+ //_NET_RESTACK_WINDOW = atoms [off++];
+ //_NET_REQUEST_FRAME_EXTENTS = atoms [off++];
+ _NET_WM_NAME = atoms [off++];
+ //_NET_WM_VISIBLE_NAME = atoms [off++];
+ //_NET_WM_ICON_NAME = atoms [off++];
+ //_NET_WM_VISIBLE_ICON_NAME = atoms [off++];
+ //_NET_WM_DESKTOP = atoms [off++];
+ _NET_WM_WINDOW_TYPE = atoms [off++];
+ _NET_WM_STATE = atoms [off++];
+ //_NET_WM_ALLOWED_ACTIONS = atoms [off++];
+ //_NET_WM_STRUT = atoms [off++];
+ //_NET_WM_STRUT_PARTIAL = atoms [off++];
+ //_NET_WM_ICON_GEOMETRY = atoms [off++];
+ _NET_WM_ICON = atoms [off++];
+ //_NET_WM_PID = atoms [off++];
+ //_NET_WM_HANDLED_ICONS = atoms [off++];
+ _NET_WM_USER_TIME = atoms [off++];
+ _NET_FRAME_EXTENTS = atoms [off++];
+ //_NET_WM_PING = atoms [off++];
+ //_NET_WM_SYNC_REQUEST = atoms [off++];
+ _NET_SYSTEM_TRAY_OPCODE = atoms [off++];
+ //_NET_SYSTEM_TRAY_ORIENTATION = atoms [off++];
+ _NET_WM_STATE_MAXIMIZED_HORZ = atoms [off++];
+ _NET_WM_STATE_MAXIMIZED_VERT = atoms [off++];
+ _NET_WM_STATE_HIDDEN = atoms [off++];
+ _XEMBED = atoms [off++];
+ _XEMBED_INFO = atoms [off++];
+ _MOTIF_WM_HINTS = atoms [off++];
+ _NET_WM_STATE_SKIP_TASKBAR = atoms [off++];
+ //_NET_WM_STATE_ABOVE = atoms [off++];
+ //_NET_WM_STATE_MODAL = atoms [off++];
+ _NET_WM_CONTEXT_HELP = atoms [off++];
+ _NET_WM_WINDOW_OPACITY = atoms [off++];
+ //_NET_WM_WINDOW_TYPE_DESKTOP = atoms [off++];
+ //_NET_WM_WINDOW_TYPE_DOCK = atoms [off++];
+ //_NET_WM_WINDOW_TYPE_TOOLBAR = atoms [off++];
+ //_NET_WM_WINDOW_TYPE_MENU = atoms [off++];
+ _NET_WM_WINDOW_TYPE_UTILITY = atoms [off++];
+ //_NET_WM_WINDOW_TYPE_DIALOG = atoms [off++];
+ //_NET_WM_WINDOW_TYPE_SPLASH = atoms [off++];
+ _NET_WM_WINDOW_TYPE_NORMAL = atoms [off++];
+ CLIPBOARD = atoms [off++];
+ PRIMARY = atoms [off++];
+ OEMTEXT = atoms [off++];
+ UNICODETEXT = atoms [off++];
+ TARGETS = atoms [off++];
+ AsyncAtom = atoms [off++];
+ PostAtom = atoms [off++];
+ HoverState.Atom = atoms [off++];
+
+ //DIB = (IntPtr)Atom.XA_PIXMAP;
+ _NET_SYSTEM_TRAY_S = XInternAtom (DisplayHandle, "_NET_SYSTEM_TRAY_S" + ScreenNo.ToString(), false);
}
private void GetSystrayManagerWindow() {
XSendEvent(DisplayHandle, window, false, new IntPtr ((int)EventMask.NoEventMask), ref xev);
}
+ // For WM_LBUTTONDOWN, WM_MBUTTONDOWN, WM_RBUTTONDOWN, WM_XBUTTONDOWN
+ // WM_CREATE and WM_DESTROY causes
+ void SendParentNotify(IntPtr child, Msg cause, int x, int y)
+ {
+ Hwnd hwnd;
+
+ if (child == IntPtr.Zero) {
+ return;
+ }
+
+ hwnd = Hwnd.GetObjectFromWindow (child);
+
+ if (hwnd == null) {
+ return;
+ }
+
+ if (hwnd.Handle == IntPtr.Zero) {
+ return;
+ }
+
+ if (ExStyleSet ((int) hwnd.initial_ex_style, WindowExStyles.WS_EX_NOPARENTNOTIFY)) {
+ return;
+ }
+
+ if (hwnd.Parent == null) {
+ return;
+ }
+
+ if (hwnd.Parent.Handle == IntPtr.Zero) {
+ return;
+ }
+
+ if (cause == Msg.WM_CREATE || cause == Msg.WM_DESTROY) {
+ SendMessage(hwnd.Parent.Handle, Msg.WM_PARENTNOTIFY, Control.MakeParam((int)cause, 0), child);
+ } else {
+ SendMessage(hwnd.Parent.Handle, Msg.WM_PARENTNOTIFY, Control.MakeParam((int)cause, 0), Control.MakeParam(x, y));
+ }
+
+ SendParentNotify (hwnd.Parent.Handle, cause, x, y);
+ }
+
bool StyleSet (int s, WindowStyles ws)
{
return (s & (int)ws) == (int)ws;
mwmHints.functions = (IntPtr)functions;
mwmHints.decorations = (IntPtr)decorations;
+ FormWindowState current_state = GetWindowState (hwnd.Handle);
+ if (current_state == (FormWindowState)(-1))
+ current_state = FormWindowState.Normal;
+
client_rect = hwnd.ClientRect;
lock (XlibLock) {
+ atom_count = 0;
+
// needed! map toolwindows to _NET_WM_WINDOW_TYPE_UTILITY to make newer metacity versions happy
// and get those windows in front of their parents
if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
atoms [0] = _NET_WM_WINDOW_TYPE_UTILITY.ToInt32 ();
XChangeProperty (DisplayHandle, hwnd.whole_window, _NET_WM_WINDOW_TYPE,
(IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
+
+ Form f = Control.FromHandle(hwnd.Handle) as Form;
+ if (f != null && !hwnd.reparented) {
+ if (f.Owner != null && f.Owner.Handle != IntPtr.Zero) {
+ Hwnd owner_hwnd = Hwnd.ObjectFromHandle(f.Owner.Handle);
+ if (owner_hwnd != null)
+ XSetTransientForHint(DisplayHandle, hwnd.whole_window,
+ owner_hwnd.whole_window);
+ }
+ }
}
XChangeProperty(DisplayHandle, hwnd.whole_window, _MOTIF_WM_HINTS, _MOTIF_WM_HINTS, 32, PropertyMode.Replace, ref mwmHints, 5);
XSetTransientForHint(DisplayHandle, hwnd.whole_window, hwnd.parent.whole_window);
} else if (!ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_APPWINDOW)) {
-// XSetTransientForHint(DisplayHandle, hwnd.whole_window, FosterParent);
+ /* this line keeps the window from showing up in gnome's taskbar */
+ atoms[atom_count++] = _NET_WM_STATE_SKIP_TASKBAR.ToInt32();
}
if ((client_rect.Width < 1) || (client_rect.Height < 1)) {
XMoveResizeWindow(DisplayHandle, hwnd.client_window, -5, -5, 1, 1);
XMoveResizeWindow(DisplayHandle, hwnd.client_window, client_rect.X, client_rect.Y, client_rect.Width, client_rect.Height);
}
- atom_count = 0;
-
if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
- atoms[atom_count++] = _NET_WM_STATE_NO_TASKBAR.ToInt32();
+ atoms[atom_count++] = _NET_WM_STATE_SKIP_TASKBAR.ToInt32();
+ }
+ /* we need to add these atoms in the
+ * event we're maximized, since we're
+ * replacing the existing
+ * _NET_WM_STATE here. If we don't
+ * add them, future calls to
+ * GetWindowState will return Normal
+ * for a window which is maximized. */
+ if (current_state == FormWindowState.Maximized) {
+ atoms[atom_count++] = _NET_WM_STATE_MAXIMIZED_HORZ.ToInt32();
+ atoms[atom_count++] = _NET_WM_STATE_MAXIMIZED_VERT.ToInt32();
}
XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_STATE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, atom_count);
XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_ICON, (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, data, size);
}
- private IntPtr ImageToPixmap(Image image) {
- return IntPtr.Zero;
- }
-
private void WakeupMain () {
wake.Send (new byte [] { 0xFF });
}
}
}
- private void InvalidateWholeWindow(IntPtr handle) {
- Hwnd hwnd;
-
- hwnd = Hwnd.ObjectFromHandle(handle);
-
- InvalidateWholeWindow(handle, new Rectangle(0, 0, hwnd.Width, hwnd.Height));
- }
-
- private void InvalidateWholeWindow(IntPtr handle, Rectangle rectangle) {
- Hwnd hwnd;
-
- hwnd = Hwnd.ObjectFromHandle(handle);
-
- AddExpose (hwnd, false, rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
- }
-
- private void WholeToScreen(IntPtr handle, ref int x, ref int y) {
- int dest_x_return;
- int dest_y_return;
- IntPtr child;
- Hwnd hwnd;
-
- hwnd = Hwnd.ObjectFromHandle(handle);
-
- lock (XlibLock) {
- XTranslateCoordinates(DisplayHandle, hwnd.whole_window, RootWindow, x, y, out dest_x_return, out dest_y_return, out child);
- }
-
- x = dest_x_return;
- 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;
}
}
}
+
+ // XXX this sucks. this isn't thread safe
hwnd.width = xevent.ConfigureEvent.width;
hwnd.height = xevent.ConfigureEvent.height;
hwnd.ClientRect = Rectangle.Empty;
- if (!hwnd.configure_pending) {
- hwnd.Queue.Enqueue(xevent);
- hwnd.configure_pending = true;
+ lock (hwnd.configure_lock) {
+ if (!hwnd.configure_pending) {
+ hwnd.Queue.EnqueueLocked (xevent);
+ hwnd.configure_pending = true;
+ }
}
}
// We drop configure events for Client windows
if (timeout > 0) {
#if __MonoCS__
- Syscall.poll (pollfds, (uint) pollfds.Length, timeout);
+ int length = pollfds.Length - 1;
+ lock (wake_waiting_lock) {
+ if (wake_waiting == false) {
+ length ++;
+ wake_waiting = true;
+ }
+ }
+
+ Syscall.poll (pollfds, (uint)length, timeout);
// Clean out buffer, so we're not busy-looping on the same data
if (pollfds[1].revents != 0) {
wake_receive.Receive(network_buffer, 0, 1, SocketFlags.None);
+ wake_waiting = false;
}
#endif
lock (XlibLock) {
}
hwnd = Hwnd.GetObjectFromWindow(xevent.AnyEvent.window);
- if (hwnd == null) {
- if (xevent.type == XEventName.Expose) {
- }
+ if (hwnd == null)
continue;
- }
switch (xevent.type) {
- case XEventName.Expose:
- AddExpose (hwnd, xevent.ExposeEvent.window == hwnd.ClientWindow, xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
- break;
+ case XEventName.Expose:
+ AddExpose (hwnd, xevent.ExposeEvent.window == hwnd.ClientWindow, xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
+ break;
- case XEventName.SelectionClear: {
- // Should we do something?
- break;
- }
+ case XEventName.SelectionClear: {
+ // Should we do something?
+ break;
+ }
- case XEventName.SelectionRequest: {
- if (Dnd.HandleSelectionRequestEvent (ref xevent))
- break;
- XEvent sel_event;
-
- sel_event = new XEvent();
- sel_event.SelectionEvent.type = XEventName.SelectionNotify;
- sel_event.SelectionEvent.send_event = true;
- sel_event.SelectionEvent.display = DisplayHandle;
- sel_event.SelectionEvent.selection = xevent.SelectionRequestEvent.selection;
- 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 = IntPtr.Zero;
-
- // Seems that some apps support asking for supported types
- if (xevent.SelectionEvent.target == TARGETS) {
- int[] atoms;
- int atom_count;
-
- atoms = new int[5];
- atom_count = 0;
-
- if (Clipboard.Item is String) {
- atoms[atom_count++] = (int)Atom.XA_STRING;
- atoms[atom_count++] = (int)OEMTEXT;
- atoms[atom_count++] = (int)UNICODETEXT;
- } else if (Clipboard.Item is Image) {
- atoms[atom_count++] = (int)Atom.XA_PIXMAP;
- atoms[atom_count++] = (int)Atom.XA_BITMAP;
- } else {
- // FIXME - handle other types
- }
+ case XEventName.SelectionRequest: {
+ if (Dnd.HandleSelectionRequestEvent (ref xevent))
+ break;
+ XEvent sel_event;
+
+ sel_event = new XEvent();
+ sel_event.SelectionEvent.type = XEventName.SelectionNotify;
+ sel_event.SelectionEvent.send_event = true;
+ sel_event.SelectionEvent.display = DisplayHandle;
+ sel_event.SelectionEvent.selection = xevent.SelectionRequestEvent.selection;
+ 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 = IntPtr.Zero;
+
+ // Seems that some apps support asking for supported types
+ if (xevent.SelectionEvent.target == TARGETS) {
+ int[] atoms;
+ int atom_count;
+
+ atoms = new int[5];
+ atom_count = 0;
+
+ if (Clipboard.Item is String) {
+ atoms[atom_count++] = (int)Atom.XA_STRING;
+ atoms[atom_count++] = (int)OEMTEXT;
+ atoms[atom_count++] = (int)UNICODETEXT;
+ } else if (Clipboard.Item is Image) {
+ atoms[atom_count++] = (int)Atom.XA_PIXMAP;
+ atoms[atom_count++] = (int)Atom.XA_BITMAP;
+ } else {
+ // FIXME - handle other types
+ }
- 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;
+ 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;
+ buflen = 0;
- if (xevent.SelectionRequestEvent.target == (IntPtr)Atom.XA_STRING) {
- Byte[] bytes;
+ if (xevent.SelectionRequestEvent.target == (IntPtr)Atom.XA_STRING) {
+ Byte[] bytes;
- bytes = new ASCIIEncoding().GetBytes((string)Clipboard.Item);
- buffer = Marshal.AllocHGlobal(bytes.Length);
- buflen = bytes.Length;
+ bytes = new ASCIIEncoding().GetBytes((string)Clipboard.Item);
+ buffer = Marshal.AllocHGlobal(bytes.Length);
+ buflen = bytes.Length;
- for (int i = 0; i < buflen; i++) {
- Marshal.WriteByte(buffer, i, bytes[i]);
- }
- } else if (xevent.SelectionRequestEvent.target == OEMTEXT) {
- // FIXME - this should encode into ISO2022
- buffer = Marshal.StringToHGlobalAnsi((string)Clipboard.Item);
- while (Marshal.ReadByte(buffer, buflen) != 0) {
- buflen++;
- }
- } else if (xevent.SelectionRequestEvent.target == UNICODETEXT) {
- buffer = Marshal.StringToHGlobalAnsi((string)Clipboard.Item);
- while (Marshal.ReadByte(buffer, buflen) != 0) {
- buflen++;
- }
- } else {
- buffer = IntPtr.Zero;
+ for (int i = 0; i < buflen; i++) {
+ Marshal.WriteByte(buffer, i, bytes[i]);
}
-
- if (buffer != IntPtr.Zero) {
- 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 (xevent.SelectionRequestEvent.target == OEMTEXT) {
+ // FIXME - this should encode into ISO2022
+ buffer = Marshal.StringToHGlobalAnsi((string)Clipboard.Item);
+ while (Marshal.ReadByte(buffer, buflen) != 0) {
+ buflen++;
}
- } else if (Clipboard.Item is Image) {
- if (xevent.SelectionEvent.target == (IntPtr)Atom.XA_PIXMAP) {
- // FIXME - convert image and store as property
- } else if (xevent.SelectionEvent.target == (IntPtr)Atom.XA_PIXMAP) {
- // FIXME - convert image and store as property
+ } else if (xevent.SelectionRequestEvent.target == UNICODETEXT) {
+ buffer = Marshal.StringToHGlobalAnsi((string)Clipboard.Item);
+ while (Marshal.ReadByte(buffer, buflen) != 0) {
+ buflen++;
}
+ } else {
+ buffer = IntPtr.Zero;
}
- XSendEvent(DisplayHandle, xevent.SelectionRequestEvent.requestor, false, new IntPtr ((int)EventMask.NoEventMask), ref sel_event);
- break;
+ if (buffer != IntPtr.Zero) {
+ 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 == (IntPtr)Atom.XA_PIXMAP) {
+ // FIXME - convert image and store as property
+ } else if (xevent.SelectionEvent.target == (IntPtr)Atom.XA_PIXMAP) {
+ // FIXME - convert image and store as property
+ }
}
- case XEventName.SelectionNotify: {
- if (Clipboard.Enumerating) {
- Clipboard.Enumerating = false;
- 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
- Console.WriteLine("Got supported clipboard atom format: {0}", xevent.SelectionEvent.property);
- #endif
- }
- }
- } else if (Clipboard.Retrieving) {
- Clipboard.Retrieving = false;
- if (xevent.SelectionEvent.property != IntPtr.Zero) {
- TranslatePropertyToClipboard(xevent.SelectionEvent.property);
- } else {
- Clipboard.Item = null;
+ 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 != IntPtr.Zero) {
+ XDeleteProperty(DisplayHandle, FosterParent, (IntPtr)xevent.SelectionEvent.property);
+ if (!Clipboard.Formats.Contains(xevent.SelectionEvent.property)) {
+ Clipboard.Formats.Add(xevent.SelectionEvent.property);
+ #if DriverDebugExtra
+ Console.WriteLine("Got supported clipboard atom format: {0}", xevent.SelectionEvent.property);
+ #endif
}
+ }
+ } else if (Clipboard.Retrieving) {
+ Clipboard.Retrieving = false;
+ if (xevent.SelectionEvent.property != IntPtr.Zero) {
+ TranslatePropertyToClipboard(xevent.SelectionEvent.property);
} else {
- Dnd.HandleSelectionNotifyEvent (ref xevent);
+ Clipboard.Item = null;
}
- break;
+ } else {
+ Dnd.HandleSelectionNotifyEvent (ref xevent);
}
+ break;
+ }
- case XEventName.MapNotify: {
- if (hwnd.client_window == xevent.MapEvent.window) {
- hwnd.mapped = true;
- }
- 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.UnmapNotify: {
+ if (hwnd.client_window == xevent.MapEvent.window) {
+ hwnd.mapped = false;
}
+ break;
+ }
- case XEventName.KeyRelease:
- if (!detectable_key_auto_repeat && XPending (DisplayHandle) != 0) {
- XEvent nextevent = new XEvent ();
+ case XEventName.KeyRelease:
+ if (!detectable_key_auto_repeat && XPending (DisplayHandle) != 0) {
+ XEvent nextevent = new XEvent ();
- XPeekEvent (DisplayHandle, ref nextevent);
+ XPeekEvent (DisplayHandle, ref nextevent);
- if (nextevent.type == XEventName.KeyPress &&
- nextevent.KeyEvent.keycode == xevent.KeyEvent.keycode &&
- nextevent.KeyEvent.time == xevent.KeyEvent.time) {
- continue;
- }
+ if (nextevent.type == XEventName.KeyPress &&
+ nextevent.KeyEvent.keycode == xevent.KeyEvent.keycode &&
+ nextevent.KeyEvent.time == xevent.KeyEvent.time) {
+ continue;
}
- goto case XEventName.KeyPress;
+ }
+ goto case XEventName.KeyPress;
- case XEventName.MotionNotify: {
- XEvent peek;
+ case XEventName.MotionNotify: {
+ XEvent peek;
- if (hwnd.Queue.Count > 0) {
- peek = hwnd.Queue.Peek();
- if (peek.AnyEvent.type == XEventName.MotionNotify) {
- continue;
- }
+ /* we can't do motion compression across threads, so just punt if we don't match up */
+ if (Thread.CurrentThread == hwnd.Queue.Thread && hwnd.Queue.Count > 0) {
+ peek = hwnd.Queue.Peek();
+ if (peek.AnyEvent.type == XEventName.MotionNotify) {
+ continue;
}
- goto case XEventName.KeyPress;
}
+ goto case XEventName.KeyPress;
+ }
+
+ case XEventName.KeyPress:
+ case XEventName.ButtonPress:
+ case XEventName.ButtonRelease:
+ case XEventName.EnterNotify:
+ case XEventName.LeaveNotify:
+ case XEventName.CreateNotify:
+ case XEventName.DestroyNotify:
+ case XEventName.FocusIn:
+ case XEventName.FocusOut:
+ case XEventName.ClientMessage:
+ case XEventName.ReparentNotify:
+ hwnd.Queue.EnqueueLocked (xevent);
+ break;
- case XEventName.KeyPress:
- case XEventName.ButtonPress:
- case XEventName.ButtonRelease:
- case XEventName.EnterNotify:
- case XEventName.LeaveNotify:
- case XEventName.CreateNotify:
- case XEventName.DestroyNotify:
- case XEventName.FocusIn:
- case XEventName.FocusOut:
- case XEventName.ClientMessage:
- case XEventName.ReparentNotify:
- hwnd.Queue.Enqueue (xevent);
- break;
-
- case XEventName.ConfigureNotify:
- AddConfigureNotify(xevent);
- break;
+ case XEventName.ConfigureNotify:
+ AddConfigureNotify(xevent);
+ break;
- case XEventName.PropertyNotify:
- if (xevent.PropertyEvent.atom == _NET_ACTIVE_WINDOW) {
- IntPtr actual_atom;
- int actual_format;
- IntPtr nitems;
- IntPtr bytes_after;
- IntPtr prop = IntPtr.Zero;
- IntPtr prev_active;;
-
- prev_active = ActiveWindow;
- XGetWindowProperty(DisplayHandle, RootWindow, _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);
-
- if (prev_active != ActiveWindow) {
- if (prev_active != IntPtr.Zero) {
- PostMessage(prev_active, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_INACTIVE, IntPtr.Zero);
- }
- if (ActiveWindow != IntPtr.Zero) {
- PostMessage(ActiveWindow, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_ACTIVE, IntPtr.Zero);
- }
+ case XEventName.PropertyNotify:
+ if (xevent.PropertyEvent.atom == _NET_ACTIVE_WINDOW) {
+ IntPtr actual_atom;
+ int actual_format;
+ IntPtr nitems;
+ IntPtr bytes_after;
+ IntPtr prop = IntPtr.Zero;
+ IntPtr prev_active;
+
+ prev_active = ActiveWindow;
+ XGetWindowProperty(DisplayHandle, RootWindow, _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);
+
+ if (prev_active != ActiveWindow) {
+ if (prev_active != IntPtr.Zero) {
+ PostMessage(prev_active, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_INACTIVE, IntPtr.Zero);
+ }
+ if (ActiveWindow != IntPtr.Zero) {
+ PostMessage(ActiveWindow, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_ACTIVE, IntPtr.Zero);
}
- if (ModalWindows.Count == 0) {
- break;
- } else {
- // Modality handling, if we are modal and the new active window is one
- // of ours but not the modal one, switch back to the modal window
-
- if (NativeWindow.FindWindow(ActiveWindow) != null) {
- if (ActiveWindow != (IntPtr)ModalWindows.Peek()) {
- Activate((IntPtr)ModalWindows.Peek());
- }
+ }
+ if (ModalWindows.Count == 0) {
+ break;
+ } else {
+ // Modality handling, if we are modal and the new active window is one
+ // of ours but not the modal one, switch back to the modal window
+
+ if (NativeWindow.FindWindow(ActiveWindow) != null) {
+ if (ActiveWindow != (IntPtr)ModalWindows.Peek()) {
+ Activate((IntPtr)ModalWindows.Peek());
}
- break;
}
+ break;
}
}
- break;
+ }
+ break;
}
}
if (ErrorExceptions) {
throw new XException(error_event.display, error_event.resourceid, error_event.serial, error_event.error_code, error_event.request_code, error_event.minor_code);
} else {
- Console.WriteLine("X11 Error encountered: {0}{1}\n", XException.GetMessage(error_event.display, error_event.resourceid, error_event.serial, error_event.error_code, error_event.request_code, error_event.minor_code), WhereString());
+ Console.WriteLine("X11 Error encountered: {0}{1}\n", XException.GetMessage(error_event.display, error_event.resourceid, error_event.serial, error_event.error_code, error_event.request_code, error_event.minor_code), Environment.StackTrace);
}
return 0;
}
- private void SendWMDestroyMessages(Control c) {
- Hwnd hwnd;
- int i;
- Control[] controls;
-
+ private void AccumulateDestroyedHandles (Control c, ArrayList list)
+ {
if (c != null) {
- controls = c.child_controls.GetAllControls ();
+ Control[] controls = c.Controls.GetAllControls ();
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>");
+ Hwnd hwnd = Hwnd.ObjectFromHandle(c.Handle);
+
+ #if DriverDebug || DriverDebugDestroy
+ Console.WriteLine (" + adding {0} to the list of zombie windows", XplatUI.Window (hwnd.Handle));
+ Console.WriteLine (" + parent X window is {0:X}", XGetParent (hwnd.whole_window).ToInt32());
#endif
- hwnd = Hwnd.ObjectFromHandle(c.Handle);
+ list.Add (hwnd);
CleanupCachedWindows (hwnd);
- SendMessage(c.Handle, Msg.WM_DESTROY, IntPtr.Zero, IntPtr.Zero);
+ hwnd.zombie = true;
}
- for (i = 0; i < controls.Length; i++) {
- if (controls[i].IsHandleCreated) {
- /* set all the children hwnd's to zombies so all events will
- be ignored (except DestroyNotify) until their X windows are
- reset) */
- hwnd = Hwnd.ObjectFromHandle(controls[i].Handle);
- hwnd.zombie = true;
- }
- SendWMDestroyMessages(controls[i]);
+ for (int i = 0; i < controls.Length; i ++) {
+ AccumulateDestroyedHandles (controls[i], list);
}
}
+
}
void CleanupCachedWindows (Hwnd hwnd)
FocusWindow = IntPtr.Zero;
}
+ if (Grab.Hwnd == hwnd.Handle) {
+ Grab.Hwnd = IntPtr.Zero;
+ Grab.Confined = false;
+ }
+
DestroyCaret (hwnd.Handle);
}
XMoveResizeWindow(DisplayHandle, hwnd.client_window, rect.X, rect.Y, rect.Width, rect.Height);
}
}
+
+ AddExpose (hwnd, false, 0, 0, hwnd.Width, hwnd.Height);
}
#endregion // Private Methods
}
}
+ internal override Point MousePosition {
+ get {
+ return mouse_position;
+ }
+ }
+
internal override Size MouseHoverSize {
get {
return new Size (1, 1);
hwnd = Hwnd.ObjectFromHandle(handle);
- if (hwnd != null) lock (XlibLock) {
- SendNetWMMessage(hwnd.whole_window, _NET_ACTIVE_WINDOW, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
- //XRaiseWindow(DisplayHandle, handle);
+ if (hwnd != null) {
+ lock (XlibLock) {
+ if (true /* the window manager supports NET_ACTIVE_WINDOW */) {
+ SendNetWMMessage(hwnd.whole_window, _NET_ACTIVE_WINDOW, (IntPtr)1, IntPtr.Zero, IntPtr.Zero);
+ }
+// else {
+// XRaiseWindow(DisplayHandle, handle);
+// }
+ }
}
- return;
}
internal override void AudibleAlert() {
//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).ToInt32();
+ else if (format == "OEMText" ) return OEMTEXT.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).ToInt32();
+ else if (format == "UnicodeText" ) return UNICODETEXT.ToInt32();
//else if (format == "EnhancedMetafile" ) return 14;
//else if (format == "FileDrop" ) return 15;
//else if (format == "Locale" ) return 16;
hwnd.width = Width;
hwnd.height = Height;
hwnd.parent = Hwnd.ObjectFromHandle(cp.Parent);
+ hwnd.initial_ex_style = (WindowExStyles) cp.ExStyle;
if (StyleSet (cp.Style, WindowStyles.WS_DISABLED)) {
hwnd.enabled = false;
}
lock (XlibLock) {
- XSelectInput(DisplayHandle, hwnd.whole_window, new IntPtr ((int)SelectInputMask));
- XSelectInput(DisplayHandle, hwnd.client_window, new IntPtr ((int)SelectInputMask));
+ XSelectInput(DisplayHandle, hwnd.whole_window, new IntPtr ((int)(SelectInputMask | EventMask.StructureNotifyMask)));
+ if (hwnd.whole_window != hwnd.client_window)
+ XSelectInput(DisplayHandle, hwnd.client_window, new IntPtr ((int)SelectInputMask));
if (StyleSet (cp.Style, WindowStyles.WS_VISIBLE)) {
MapWindow(hwnd, WindowType.Both);
XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_WINDOW_TYPE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
XSetTransientForHint (DisplayHandle, hwnd.whole_window, RootWindow);
- } else if (!ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_APPWINDOW)) {
-// XSetTransientForHint (DisplayHandle, hwnd.whole_window, FosterParent);
}
SetWMStyles(hwnd, cp);
// Set caption/window title
Text(hwnd.Handle, cp.Caption);
+
+ SendParentNotify (hwnd.Handle, Msg.WM_CREATE, int.MaxValue, int.MaxValue);
return hwnd.Handle;
}
internal override void DestroyCaret(IntPtr handle) {
if (Caret.Hwnd == handle) {
- if (Caret.Visible == true) {
+ if (Caret.Visible) {
+ HideCaret ();
Caret.Timer.Stop();
}
if (Caret.gc != IntPtr.Zero) {
}
#if DriverDebug || DriverDebugDestroy
- Console.WriteLine("Destroying window {0:X}", handle.ToInt32());
+ Console.WriteLine("Destroying window {0}", XplatUI.Window(hwnd.client_window));
#endif
+ SendParentNotify (hwnd.Handle, Msg.WM_DESTROY, int.MaxValue, int.MaxValue);
+
CleanupCachedWindows (hwnd);
- SendWMDestroyMessages(Control.ControlNativeWindow.ControlFromHandle(hwnd.Handle));
+ ArrayList windows = new ArrayList ();
+
+ AccumulateDestroyedHandles (Control.ControlNativeWindow.ControlFromHandle(hwnd.Handle), windows);
lock (XlibLock) {
if (hwnd.whole_window != IntPtr.Zero) {
+ #if DriverDebug || DriverDebugDestroy
+ Console.WriteLine ("XDestroyWindow (whole_window = {0:X})", hwnd.whole_window.ToInt32());
+ #endif
XDestroyWindow(DisplayHandle, hwnd.whole_window);
}
else if (hwnd.client_window != IntPtr.Zero) {
+ #if DriverDebug || DriverDebugDestroy
+ Console.WriteLine ("XDestroyWindow (client_window = {0:X})", hwnd.client_window.ToInt32());
+ #endif
XDestroyWindow(DisplayHandle, hwnd.client_window);
}
}
- hwnd.Dispose();
+
+ foreach (Hwnd h in windows) {
+ SendMessage (h.Handle, Msg.WM_DESTROY, IntPtr.Zero, IntPtr.Zero);
+ }
}
internal override IntPtr DispatchMessage(ref MSG msg) {
return NativeWindow.WndProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
}
- internal override void DrawReversibleRectangle(IntPtr handle, Rectangle rect, int line_width) {
- Hwnd hwnd;
+ IntPtr GetReversibleScreenGC (Color backColor)
+ {
XGCValues gc_values;
IntPtr gc;
+ uint pixel;
- hwnd = Hwnd.ObjectFromHandle(handle);
+ XColor xcolor = new XColor();
+ xcolor.red = (ushort)(backColor.R * 257);
+ xcolor.green = (ushort)(backColor.G * 257);
+ xcolor.blue = (ushort)(backColor.B * 257);
+ XAllocColor(DisplayHandle, DefaultColormap, ref xcolor);
+ pixel = (uint)xcolor.pixel.ToInt32();
+
+
+ gc_values = new XGCValues();
+
+ gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
+ gc_values.foreground = (IntPtr)pixel;
+
+ gc = XCreateGC(DisplayHandle, RootWindow, new IntPtr ((int) (GCFunction.GCSubwindowMode | GCFunction.GCForeground)), ref gc_values);
+ XSetForeground(DisplayHandle, gc, (UIntPtr)pixel);
+ XSetFunction(DisplayHandle, gc, GXFunction.GXxor);
+
+ return gc;
+ }
+
+ IntPtr GetReversibleControlGC (Control control, int line_width)
+ {
+ XGCValues gc_values;
+ IntPtr gc;
gc_values = new XGCValues();
//XSetPlaneMask(DisplayHandle, gc, mask);
- gc = XCreateGC(DisplayHandle, hwnd.client_window, new IntPtr ((int) (GCFunction.GCSubwindowMode | GCFunction.GCLineWidth | GCFunction.GCForeground)), ref gc_values);
+ gc = XCreateGC(DisplayHandle, control.Handle, new IntPtr ((int) (GCFunction.GCSubwindowMode | GCFunction.GCLineWidth | GCFunction.GCForeground)), ref gc_values);
uint foreground;
uint background;
- Control control;
- control = Control.FromHandle(handle);
-
XColor xcolor = new XColor();
xcolor.red = (ushort)(control.ForeColor.R * 257);
XSetFunction(DisplayHandle, gc, GXFunction.GXxor);
XSetPlaneMask(DisplayHandle, gc, (IntPtr)mask);
+ return gc;
+ }
+
+ internal override void DrawReversibleLine(Point start, Point end, Color backColor)
+ {
+ IntPtr gc = GetReversibleScreenGC (backColor);
+
+ XDrawLine (DisplayHandle, RootWindow, gc, start.X, start.Y, end.X, end.Y);
+
+ XFreeGC(DisplayHandle, gc);
+ }
+
+ internal override void DrawReversibleFrame (Rectangle rectangle, Color backColor, FrameStyle style)
+ {
+ IntPtr gc = GetReversibleScreenGC (backColor);
+
+ if (rectangle.Width < 0) {
+ rectangle.X += rectangle.Width;
+ rectangle.Width = -rectangle.Width;
+ }
+ if (rectangle.Height < 0) {
+ rectangle.Y += rectangle.Height;
+ rectangle.Height = -rectangle.Height;
+ }
+
+ int line_width = 1;
+ GCLineStyle line_style = GCLineStyle.LineSolid;
+ GCCapStyle cap_style = GCCapStyle.CapButt;
+ GCJoinStyle join_style = GCJoinStyle.JoinMiter;
+
+ switch (style) {
+ case FrameStyle.Dashed:
+ line_style = GCLineStyle.LineOnOffDash;
+ break;
+ case FrameStyle.Thick:
+ line_width = 2;
+ break;
+ }
+
+ XSetLineAttributes (DisplayHandle, gc, line_width, line_style, cap_style, join_style);
+
+ XDrawRectangle(DisplayHandle, RootWindow, gc, rectangle.Left, rectangle.Top, rectangle.Width, rectangle.Height);
+
+ XFreeGC(DisplayHandle, gc);
+ }
+
+ internal override void FillReversibleRectangle (Rectangle rectangle, Color backColor)
+ {
+ IntPtr gc = GetReversibleScreenGC (backColor);
+
+ if (rectangle.Width < 0) {
+ rectangle.X += rectangle.Width;
+ rectangle.Width = -rectangle.Width;
+ }
+ if (rectangle.Height < 0) {
+ rectangle.Y += rectangle.Height;
+ rectangle.Height = -rectangle.Height;
+ }
+ XFillRectangle(DisplayHandle, RootWindow, gc, rectangle.Left, rectangle.Top, rectangle.Width, rectangle.Height);
+
+ XFreeGC(DisplayHandle, gc);
+ }
+
+ internal override void DrawReversibleRectangle(IntPtr handle, Rectangle rect, int line_width) {
+ IntPtr gc;
+ Control control = Control.FromHandle(handle);
+
+ gc = GetReversibleControlGC (control, line_width);
+
if ((rect.Width > 0) && (rect.Height > 0)) {
- XDrawRectangle(DisplayHandle, hwnd.client_window, gc, rect.Left, rect.Top, rect.Width, rect.Height);
+ XDrawRectangle(DisplayHandle, control.Handle, gc, rect.Left, rect.Top, rect.Width, rect.Height);
} else {
if (rect.Width > 0) {
- XDrawLine(DisplayHandle, hwnd.client_window, gc, rect.X, rect.Y, rect.Right, rect.Y);
+ XDrawLine(DisplayHandle, control.Handle, gc, rect.X, rect.Y, rect.Right, rect.Y);
} else {
- XDrawLine(DisplayHandle, hwnd.client_window, gc, rect.X, rect.Y, rect.X, rect.Bottom);
+ XDrawLine(DisplayHandle, control.Handle, gc, rect.X, rect.Y, rect.X, rect.Bottom);
}
}
XFreeGC(DisplayHandle, gc);
// Handle messages for windows that are already or are about to be destroyed.
+ // we need a special block for this because unless we remove the hwnd from the paint
+ // queue it will always stay there (since we don't handle the expose), and we'll
+ // effectively loop infinitely trying to repaint a non-existant window.
+ if (hwnd != null && hwnd.zombie && xevent.type == XEventName.Expose) {
+ hwnd.expose_pending = hwnd.nc_expose_pending = false;
+ hwnd.Queue.Paint.Remove (hwnd);
+ goto ProcessNextMessage;
+ }
+
// We need to make sure we only allow DestroyNotify events through for zombie
// hwnds, since much of the event handling code makes requests using the hwnd's
// client_window, and that'll result in BadWindow errors if there's some lag
// between the XDestroyWindow call and the DestroyNotify event.
- if (hwnd == null || (hwnd.zombie && xevent.type != XEventName.DestroyNotify)) {
- #if DriverDebug
+ if (hwnd == null || hwnd.zombie) {
+ #if DriverDebug || DriverDebugDestroy
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) {
client = true;
- //Console.WriteLine("Client message, sending to window {0:X}", msg.hwnd.ToInt32());
+ //Console.WriteLine("Client message {1}, sending to window {0:X}", msg.hwnd.ToInt32(), xevent.type);
} else {
client = false;
//Console.WriteLine("Non-Client message, sending to window {0:X}", msg.hwnd.ToInt32());
}
msg.lParam=(IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
- MousePosition.X = xevent.ButtonEvent.x;
- MousePosition.Y = xevent.ButtonEvent.y;
+ mouse_position.X = xevent.ButtonEvent.x;
+ mouse_position.Y = xevent.ButtonEvent.y;
if (!hwnd.Enabled) {
IntPtr dummy;
msg.hwnd = hwnd.EnabledHwnd;
XTranslateCoordinates(DisplayHandle, xevent.AnyEvent.window, Hwnd.ObjectFromHandle(msg.hwnd).ClientWindow, xevent.ButtonEvent.x, xevent.ButtonEvent.y, out xevent.ButtonEvent.x, out xevent.ButtonEvent.y, out dummy);
- msg.lParam = (IntPtr)(MousePosition.Y << 16 | MousePosition.X);
+ msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
}
if (Grab.Hwnd != IntPtr.Zero) {
ClickPending.lParam = msg.lParam;
ClickPending.Time = (long)xevent.ButtonEvent.time;
}
-
+
+ if (msg.message == Msg.WM_LBUTTONDOWN || msg.message == Msg.WM_MBUTTONDOWN || msg.message == Msg.WM_RBUTTONDOWN)
+ SendParentNotify(msg.hwnd, msg.message, mouse_position.X, mouse_position.Y);
+
break;
}
switch(xevent.ButtonEvent.button) {
case 1: {
- MouseState &= ~MouseButtons.Left;
if (client) {
msg.message = Msg.WM_LBUTTONUP;
} else {
msg.message = Msg.WM_NCLBUTTONUP;
MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
}
+ MouseState &= ~MouseButtons.Left;
msg.wParam=GetMousewParam(0);
break;
}
case 2: {
- MouseState &= ~MouseButtons.Middle;
if (client) {
msg.message = Msg.WM_MBUTTONUP;
} else {
msg.message = Msg.WM_NCMBUTTONUP;
MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
}
+ MouseState &= ~MouseButtons.Middle;
msg.wParam=GetMousewParam(0);
break;
}
case 3: {
- MouseState &= ~MouseButtons.Right;
if (client) {
msg.message = Msg.WM_RBUTTONUP;
} else {
msg.message = Msg.WM_NCRBUTTONUP;
MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
}
+ MouseState &= ~MouseButtons.Right;
msg.wParam=GetMousewParam(0);
break;
}
msg.hwnd = hwnd.EnabledHwnd;
XTranslateCoordinates(DisplayHandle, xevent.AnyEvent.window, Hwnd.ObjectFromHandle(msg.hwnd).ClientWindow, xevent.ButtonEvent.x, xevent.ButtonEvent.y, out xevent.ButtonEvent.x, out xevent.ButtonEvent.y, out dummy);
- msg.lParam = (IntPtr)(MousePosition.Y << 16 | MousePosition.X);
+ msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
}
if (Grab.Hwnd != IntPtr.Zero) {
}
msg.lParam=(IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
- MousePosition.X = xevent.ButtonEvent.x;
- MousePosition.Y = xevent.ButtonEvent.y;
+ mouse_position.X = xevent.ButtonEvent.x;
+ mouse_position.Y = xevent.ButtonEvent.y;
break;
}
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);
+ msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
}
- MousePosition.X = xevent.MotionEvent.x;
- MousePosition.Y = xevent.MotionEvent.y;
+ mouse_position.X = xevent.MotionEvent.x;
+ mouse_position.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))) {
+ (((mouse_position.X + HoverState.Size.Width) < HoverState.X) ||
+ ((mouse_position.X - HoverState.Size.Width) > HoverState.X) ||
+ ((mouse_position.Y + HoverState.Size.Height) < HoverState.Y) ||
+ ((mouse_position.Y - HoverState.Size.Height) > HoverState.Y))) {
HoverState.Timer.Stop();
HoverState.Timer.Start();
- HoverState.X = MousePosition.X;
- HoverState.Y = MousePosition.Y;
+ HoverState.X = mouse_position.X;
+ HoverState.Y = mouse_position.Y;
}
break;
if (!hwnd.Enabled) {
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);
+ msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
}
// The hit test is sent in screen coordinates
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;
+ mouse_position.X = xevent.MotionEvent.x;
+ mouse_position.Y = xevent.MotionEvent.y;
}
break;
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
// if ((hwnd.x != xevent.ConfigureEvent.x) || (hwnd.y != xevent.ConfigureEvent.y) || (hwnd.width != xevent.ConfigureEvent.width) || (hwnd.height != xevent.ConfigureEvent.height)) {
- SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
- hwnd.configure_pending = false;
+ lock (hwnd.configure_lock) {
+ 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
- PerformNCCalc(hwnd);
+ if (hwnd.whole_window != hwnd.client_window)
+ PerformNCCalc(hwnd);
// }
}
goto ProcessNextMessage;
IntPtr hrgn = region.GetHrgn (null); // Graphics object isn't needed
msg.message = Msg.WM_NCPAINT;
msg.wParam = hrgn == IntPtr.Zero ? (IntPtr)1 : hrgn;
+ msg.refobject = region;
break;
}
#if DriverDebugExtra
msg.hwnd = hwnd.client_window;
msg.message=Msg.WM_DESTROY;
hwnd.Dispose();
-
- #if DriverDebug
- Console.WriteLine("Got DestroyNotify on Window {0:X}", msg.hwnd.ToInt32());
- #endif
} else {
goto ProcessNextMessage;
}
return true;
}
- #if dontcare
if (xevent.ClientMessageEvent.message_type == _XEMBED) {
- Console.WriteLine("GOT EMBED MESSAGE {0:X}", xevent.ClientMessageEvent.ptr2.ToInt32());
- break;
+#if DriverDebugXEmbed
+ Console.WriteLine("GOT EMBED MESSAGE {0:X}, detail {1:X}", xevent.ClientMessageEvent.ptr2.ToInt32(), xevent.ClientMessageEvent.ptr3.ToInt32());
+#endif
+
+ if (xevent.ClientMessageEvent.ptr2.ToInt32() == (int)XEmbedMessage.EmbeddedNotify) {
+ XSizeHints hints = new XSizeHints();
+ IntPtr dummy;
+
+ XGetWMNormalHints(DisplayHandle, hwnd.whole_window, ref hints, out dummy);
+
+ hwnd.width = hints.max_width;
+ hwnd.height = hints.max_height;
+ hwnd.ClientRect = Rectangle.Empty;
+ SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
+ }
}
- #endif
if (xevent.ClientMessageEvent.message_type == WM_PROTOCOLS) {
if (xevent.ClientMessageEvent.ptr1 == WM_DELETE_WINDOW) {
goto ProcessNextMessage;
}
- case XEventName.TimerNotify: {
- xevent.TimerNotifyEvent.handler (this, EventArgs.Empty);
- goto ProcessNextMessage;
- }
-
default: {
goto ProcessNextMessage;
}
}
internal override bool GetText(IntPtr handle, out string text) {
- IntPtr textptr;
-
- textptr = IntPtr.Zero;
lock (XlibLock) {
- // FIXME - use _NET properties
- XFetchName(DisplayHandle, Hwnd.ObjectFromHandle(handle).whole_window, ref textptr);
- }
- if (textptr != IntPtr.Zero) {
- text = Marshal.PtrToStringAnsi(textptr);
- XFree(textptr);
- return true;
- } else {
- text = "";
- return false;
+ IntPtr actual_atom;
+ int actual_format;
+ IntPtr nitems;
+ IntPtr bytes_after;
+ IntPtr prop = IntPtr.Zero;
+
+ XGetWindowProperty(DisplayHandle, handle,
+ _NET_WM_NAME, IntPtr.Zero, new IntPtr (1), false,
+ UNICODETEXT, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
+
+ if ((long)nitems > 0 && prop != IntPtr.Zero) {
+ text = Marshal.PtrToStringUni (prop, (int)nitems);
+ XFree (prop);
+ return true;
+ }
+ else {
+ // fallback on the non-_NET property
+ IntPtr textptr;
+
+ textptr = IntPtr.Zero;
+
+ XFetchName(DisplayHandle, Hwnd.ObjectFromHandle(handle).whole_window, ref textptr);
+ if (textptr != IntPtr.Zero) {
+ text = Marshal.PtrToStringAnsi(textptr);
+ XFree(textptr);
+ return true;
+ } else {
+ text = "";
+ return false;
+ }
+ }
}
}
attributes = new XWindowAttributes();
XGetWindowAttributes(DisplayHandle, hwnd.client_window, ref attributes);
if (attributes.map_state == MapState.IsUnmapped) {
- throw new NotSupportedException("Cannot retrieve the state of an unmapped window");
+ return (FormWindowState)(-1);
}
}
}
+ internal override void InvalidateNC (IntPtr handle) {
+ Hwnd hwnd;
+
+ hwnd = Hwnd.ObjectFromHandle(handle);
+
+ AddExpose (hwnd, false, 0, 0, hwnd.Width, hwnd.Height);
+ }
+
internal override bool IsEnabled(IntPtr handle) {
Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
return (hwnd != null && hwnd.Enabled);
Caret.Paused = true;
HideCaret();
}
-
- if (client) {
-#if true
- hwnd.client_dc = Graphics.FromHwnd (hwnd.client_window);
-#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
+ Graphics dc;
+
+ if (client) {
+ dc = Graphics.FromHwnd (hwnd.client_window);
Region clip_region = new Region ();
clip_region.MakeEmpty();
clip_region.Intersect(hwnd.UserClip);
}
- hwnd.client_dc.Clip = clip_region;
- paint_event = new PaintEventArgs(hwnd.client_dc, hwnd.Invalid);
+ dc.Clip = clip_region;
+ paint_event = new PaintEventArgs(dc, hwnd.Invalid);
hwnd.expose_pending = false;
hwnd.ClearInvalidArea();
+ hwnd.drawing_stack.Push (paint_event);
+ hwnd.drawing_stack.Push (dc);
+
return paint_event;
} else {
- hwnd.non_client_dc = Graphics.FromHwnd (hwnd.whole_window);
+ 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);
+ dc.SetClip (hwnd.nc_invalid);
+ paint_event = new PaintEventArgs(dc, hwnd.nc_invalid);
} else {
- paint_event = new PaintEventArgs(hwnd.non_client_dc, new Rectangle(0, 0, hwnd.width, hwnd.height));
+ paint_event = new PaintEventArgs(dc, new Rectangle(0, 0, hwnd.width, hwnd.height));
}
hwnd.nc_expose_pending = false;
hwnd.ClearNcInvalidArea ();
+ hwnd.drawing_stack.Push (paint_event);
+ hwnd.drawing_stack.Push (dc);
+
return paint_event;
}
}
hwnd = Hwnd.ObjectFromHandle(handle);
- if (client) {
-#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.non_client_dc.Flush ();
- hwnd.non_client_dc.Dispose ();
- hwnd.non_client_dc = null;
- }
-
+ Graphics dc = (Graphics)hwnd.drawing_stack.Pop ();
+ dc.Flush();
+ dc.Dispose();
+
+ PaintEventArgs pe = (PaintEventArgs)hwnd.drawing_stack.Pop();
+ pe.SetGraphics (null);
+ pe.Dispose ();
if (Caret.Visible == true) {
ShowCaret();
xevent.ClientMessageEvent.ptr3 = wparam;
xevent.ClientMessageEvent.ptr4 = lparam;
- hwnd.Queue.Enqueue (xevent);
+ hwnd.Queue.EnqueueLocked (xevent);
return true;
}
ThreadQueue(Thread.CurrentThread).PostQuitState = true;
}
+ internal override void RequestAdditionalWM_NCMessages(IntPtr hwnd, bool hover, bool leave)
+ {
+ // TODO
+ }
+
internal override void RequestNCRecalc(IntPtr handle) {
Hwnd hwnd;
PerformNCCalc(hwnd);
SendMessage(handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
- InvalidateWholeWindow(handle);
+ InvalidateNC(handle);
}
internal override void ResetMouseHover(IntPtr handle) {
}
HoverState.Timer.Enabled = true;
- HoverState.X = MousePosition.X;
- HoverState.Y = MousePosition.Y;
+ HoverState.X = mouse_position.X;
+ HoverState.Y = mouse_position.Y;
HoverState.Window = handle;
}
Hwnd hwnd;
IntPtr gc;
XGCValues gc_values;
- Rectangle r;
hwnd = Hwnd.ObjectFromHandle(handle);
- r = hwnd.Invalid;
- if (r != Rectangle.Empty) {
+ Rectangle r = Rectangle.Intersect (hwnd.Invalid, area);
+ if (!r.IsEmpty) {
/* We have an invalid area in the window we're scrolling.
Adjust our stored invalid rectangle to to match the scrolled amount */
r.Y =0;
}
- hwnd.ClearInvalidArea();
+ if (area.Contains (hwnd.Invalid))
+ hwnd.ClearInvalidArea ();
hwnd.AddInvalidArea(r);
}
Hwnd h;
h = Hwnd.ObjectFromHandle(hwnd);
- if (h.queue != ThreadQueue (Thread.CurrentThread)) {
+ if (h != null && h.queue != ThreadQueue (Thread.CurrentThread)) {
AsyncMethodResult result;
AsyncMethodData data;
data.Result = result;
SendAsyncMethod (data);
- #if DriverDebug || DriverDebugParent
+ #if DriverDebug || DriverDebugThreads
Console.WriteLine ("Sending {0} message across.", message);
#endif
return NativeWindow.WndProc(hwnd, message, wParam, lParam);
}
+ internal override int SendInput(IntPtr handle, Queue keys) {
+ int count = keys.Count;
+
+ while (keys.Count > 0) {
+
+ MSG msg = (MSG)keys.Dequeue();
+
+ XEvent xevent = new XEvent ();
+ Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
+
+ xevent.type = (msg.message == Msg.WM_KEYUP ? XEventName.KeyRelease : XEventName.KeyPress);
+ xevent.KeyEvent.display = DisplayHandle;
+
+ if (hwnd != null) {
+ xevent.KeyEvent.window = hwnd.whole_window;
+ } else {
+ xevent.KeyEvent.window = IntPtr.Zero;
+ }
+
+ xevent.KeyEvent.keycode = Keyboard.ToKeycode((int)msg.wParam);
+
+ hwnd.Queue.EnqueueLocked (xevent);
+ }
+ return count;
+ }
+
+
internal override void SetAllowDrop (IntPtr handle, bool value)
{
// We allow drop on all windows
return;
}
- Control c = Control.FromHandle (child_hwnd.Handle);
-
XEvent xevent = new XEvent ();
xevent.type = XEventName.MotionNotify;
xevent.MotionEvent.y_root = root_y;
xevent.MotionEvent.state = mask;
- child_hwnd.Queue.Enqueue (xevent);
+ child_hwnd.Queue.EnqueueLocked (xevent);
}
} else {
Hwnd hwnd;
return true;
}
- internal override bool SetVisible(IntPtr handle, bool visible) {
+ internal override bool SetVisible(IntPtr handle, bool visible, bool activate) {
Hwnd hwnd;
hwnd = Hwnd.ObjectFromHandle(handle);
return;
}
+ // Win32 automatically changes negative width/height to 0.
+ if (width < 0)
+ width = 0;
+ if (height < 0)
+ height = 0;
+
// X requires a sanity check for width & height; otherwise it dies
if (hwnd.zero_sized && width > 0 && height > 0) {
if (hwnd.visible) {
}
}
- // Prevent an old queued ConfigureNotify from setting our width with outdated data, set it now
+ // Update our position/size immediately, so
+ // that future calls to SetWindowPos aren't
+ // kept from calling XMoveResizeWindow (by the
+ // "Save a server roundtrip" block above).
+ hwnd.x = x;
+ hwnd.y = y;
hwnd.width = width;
hwnd.height = height;
+ hwnd.ClientRect = Rectangle.Empty;
}
internal override void SetWindowState(IntPtr handle, FormWindowState state) {
hwnd = Hwnd.ObjectFromHandle(handle);
- try {
- current_state = GetWindowState(handle);
- }
- catch (NotSupportedException) {
- current_state = (FormWindowState)(-1);
- }
+ current_state = GetWindowState(handle);
if (current_state == state) {
return;
SetWMStyles(hwnd, cp);
}
+ internal override double GetWindowTransparency(IntPtr handle)
+ {
+ return 1.0;
+ }
+
internal override void SetWindowTransparency(IntPtr handle, double transparency, Color key) {
Hwnd hwnd;
IntPtr opacity;
hwnd.opacity = (uint)(0xffffffff * transparency);
opacity = (IntPtr)((int)hwnd.opacity);
- if (hwnd.reparented) {
- XChangeProperty(DisplayHandle, XGetParent(hwnd.whole_window), _NET_WM_WINDOW_OPACITY, (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, ref opacity, 1);
- }
+ IntPtr w = hwnd.whole_window;
+ if (hwnd.reparented)
+ w = XGetParent (hwnd.whole_window);
+ XChangeProperty(DisplayHandle, w, _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) {
XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_USER_TIME, (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, atoms, 1);
XRaiseWindow(DisplayHandle, hwnd.whole_window);
- SendNetWMMessage(hwnd.whole_window, _NET_ACTIVE_WINDOW, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
+ SendNetWMMessage(hwnd.whole_window, _NET_ACTIVE_WINDOW, (IntPtr)1, IntPtr.Zero, IntPtr.Zero);
return true;
//throw new ArgumentNullException("after_handle", "Need sibling to adjust z-order");
}
return (Object) ThreadQueue(thread);
}
- internal override bool SupportsTransparency() {
+ internal override TransparencySupport SupportsTransparency() {
// We need to check if the x compositing manager is running
- return true;
+ return TransparencySupport.Set;
}
internal override bool SystrayAdd(IntPtr handle, string tip, Icon icon, out ToolTip tt) {
if (SystrayMgrWindow != IntPtr.Zero) {
XSizeHints size_hints;
- IntPtr dummy;
Hwnd hwnd;
hwnd = Hwnd.ObjectFromHandle(handle);
if (hwnd.client_window != hwnd.whole_window) {
XDestroyWindow(DisplayHandle, hwnd.client_window);
hwnd.client_window = hwnd.whole_window;
+
+ /* by virtue of the way the tests are ordered when determining if it's PAINT
+ or NCPAINT, client_window == whole_window will always be PAINT. So, if we're
+ waiting on an nc_expose, drop it and remove the hwnd from the list (unless
+ there's a pending expose). */
+ if (hwnd.nc_expose_pending) {
+ hwnd.nc_expose_pending = false;
+ if (!hwnd.expose_pending)
+ hwnd.Queue.Paint.Remove (hwnd);
+ }
}
size_hints = new XSizeHints();
- XGetWMNormalHints(DisplayHandle, hwnd.whole_window, ref size_hints, out dummy);
size_hints.flags = (IntPtr)(XSizeHintsFlags.PMinSize | XSizeHintsFlags.PMaxSize | XSizeHintsFlags.PBaseSize);
- size_hints.min_width = icon.Width;
- size_hints.min_height = icon.Height;
- size_hints.max_width = icon.Width;
- size_hints.max_height = icon.Height;
+ size_hints.min_width = 24;
+ size_hints.min_height = 24;
+ size_hints.max_width = 24;
+ size_hints.max_height = 24;
+ size_hints.base_width = 24;
+ size_hints.base_height = 24;
- size_hints.base_width = icon.Width;
- size_hints.base_height = icon.Height;
XSetWMNormalHints(DisplayHandle, hwnd.whole_window, ref size_hints);
int[] atoms = new int[2];
}
internal override bool Text(IntPtr handle, string text) {
+ Hwnd hwnd;
+
+ hwnd = Hwnd.ObjectFromHandle(handle);
+
lock (XlibLock) {
- // FIXME - use _NET properties
+ XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_NAME, UNICODETEXT, 8,
+ PropertyMode.Replace, text, Encoding.UTF8.GetByteCount (text));
+
+ // XXX this has problems with UTF8.
+ // we need to either use the actual
+ // text if it's latin-1, or convert it
+ // to compound text if it's in a
+ // different charset.
XStoreName(DisplayHandle, Hwnd.ObjectFromHandle(handle).whole_window, text);
}
return true;
hwnd.Queue.Paint.Remove(hwnd);
}
+ internal override void CreateOffscreenDrawable (IntPtr handle,
+ int width, int height,
+ out object offscreen_drawable)
+ {
+ IntPtr root_out;
+ int x_out, y_out, width_out, height_out, border_width_out, depth_out;
+
+ XGetGeometry (DisplayHandle, handle,
+ out root_out,
+ out x_out, out y_out,
+ out width_out, out height_out,
+ out border_width_out, out depth_out);
+
+ IntPtr pixmap = XCreatePixmap (DisplayHandle, handle, width, height, depth_out);
+
+ offscreen_drawable = pixmap;
+
+ }
+
+ internal override void DestroyOffscreenDrawable (object offscreen_drawable)
+ {
+ XFreePixmap (DisplayHandle, (IntPtr)offscreen_drawable);
+ }
+
+ internal override Graphics GetOffscreenGraphics (object offscreen_drawable)
+ {
+ return Graphics.FromHwnd ((IntPtr) offscreen_drawable);
+ }
+
+ internal override void BlitFromOffscreen (IntPtr dest_handle,
+ Graphics dest_dc,
+ object offscreen_drawable,
+ Graphics offscreen_dc,
+ Rectangle r)
+ {
+ XGCValues gc_values;
+ IntPtr gc;
+
+ gc_values = new XGCValues();
+
+ gc = XCreateGC (DisplayHandle, dest_handle, IntPtr.Zero, ref gc_values);
+
+ XCopyArea (DisplayHandle, (IntPtr)offscreen_drawable, dest_handle,
+ gc, r.X, r.Y, r.Width, r.Height, r.X, r.Y);
+
+ XFreeGC (DisplayHandle, gc);
+ }
+
#endregion // Public Static Methods
#region Events
[DllImport ("libX11", EntryPoint="XInternAtom")]
internal extern static IntPtr XInternAtom(IntPtr display, string atom_name, bool only_if_exists);
+ [DllImport ("libX11", EntryPoint="XInternAtoms")]
+ internal extern static int XInternAtoms(IntPtr display, string[] atom_names, int atom_count, bool only_if_exists, IntPtr[] atoms);
+
[DllImport ("libX11", EntryPoint="XSetWMProtocols")]
internal extern static int XSetWMProtocols(IntPtr display, IntPtr window, IntPtr[] protocols, int count);
[DllImport ("libX11", EntryPoint="XSetFunction")]
internal extern static int XSetFunction(IntPtr display, IntPtr gc, GXFunction function);
+ [DllImport ("libX11", EntryPoint="XSetLineAttributes")]
+ internal extern static int XSetLineAttributes(IntPtr display, IntPtr gc, int line_width, GCLineStyle line_style, GCCapStyle cap_style, GCJoinStyle join_style);
+
[DllImport ("libX11", EntryPoint="XDrawLine")]
internal extern static int XDrawLine(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2);
[DllImport ("libX11", EntryPoint="XDrawRectangle")]
internal extern static int XDrawRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
+ [DllImport ("libX11", EntryPoint="XFillRectangle")]
+ internal extern static int XFillRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
+
[DllImport ("libX11", EntryPoint="XSetWindowBackground")]
internal extern static int XSetWindowBackground(IntPtr display, IntPtr window, IntPtr background);
[DllImport ("libX11", EntryPoint="XCreatePixmapFromBitmapData")]
internal extern static IntPtr XCreatePixmapFromBitmapData(IntPtr display, IntPtr drawable, byte[] data, int width, int height, IntPtr fg, IntPtr bg, int depth);
+ [DllImport ("libX11", EntryPoint="XCreatePixmap")]
+ internal extern static IntPtr XCreatePixmap(IntPtr display, IntPtr d, int width, int height, int depth);
+
[DllImport ("libX11", EntryPoint="XFreePixmap")]
internal extern static IntPtr XFreePixmap(IntPtr display, IntPtr pixmap);