internal void SetDisplay(IntPtr display_handle) {
if (display_handle != IntPtr.Zero) {
Hwnd hwnd;
if ((DisplayHandle != IntPtr.Zero) && (FosterParent != IntPtr.Zero)) {
hwnd = Hwnd.ObjectFromHandle(FosterParent);
XDestroyWindow(DisplayHandle, FosterParent);
hwnd.Dispose();
}
if (DisplayHandle != IntPtr.Zero) {
XCloseDisplay(DisplayHandle);
}
DisplayHandle=display_handle;
// We need to tell System.Drawing our DisplayHandle. FromHdcInternal has
// been hacked to do this for us.
Graphics.FromHdcInternal (DisplayHandle);
// query for the render extension so
// we can ignore the spurious
// BadPicture errors that are
// generated by cairo/render.
XQueryExtension (DisplayHandle, "RENDER",
ref render_major_opcode, ref render_first_event, ref render_first_error);
// Debugging support
if (Environment.GetEnvironmentVariable ("MONO_XSYNC") != null) {
XSynchronize(DisplayHandle, true);
}
if (Environment.GetEnvironmentVariable ("MONO_XEXCEPTIONS") != null) {
ErrorExceptions = true;
}
// Generic X11 setup
ScreenNo = XDefaultScreen(DisplayHandle);
RootWindow = XRootWindow(DisplayHandle, ScreenNo);
DefaultColormap = XDefaultColormap(DisplayHandle, ScreenNo);
// Create the foster parent
// it is important that border_width is kept in synch with the other XCreateWindow calls
FosterParent=XCreateSimpleWindow(DisplayHandle, RootWindow, 0, 0, 1, 1, 0, UIntPtr.Zero, UIntPtr.Zero);
if (FosterParent==IntPtr.Zero) {
Console.WriteLine("XplatUIX11 Constructor failed to create FosterParent");
}
DebugHelper.WriteLine ("FosterParent created 0x{0:x}", FosterParent.ToInt32());
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);
listen.Bind(ep);
listen.Listen(1);
// To wake up when a timer is ready
network_buffer = new byte[10];
wake = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
wake.Connect(listen.LocalEndPoint);
wake_receive = listen.Accept();
#if __MonoCS__
pollfds = new Pollfd [2];
pollfds [0] = new Pollfd ();
pollfds [0].fd = XConnectionNumber (DisplayHandle);
pollfds [0].events = PollEvents.POLLIN;
pollfds [1] = new Pollfd ();
pollfds [1].fd = wake_receive.Handle.ToInt32 ();
pollfds [1].events = PollEvents.POLLIN;
#endif
Keyboard = new X11Keyboard(DisplayHandle, FosterParent);
Dnd = new X11Dnd (DisplayHandle, Keyboard);
DoubleClickInterval = 500;
HoverState.Interval = 500;
HoverState.Timer = new Timer();
HoverState.Timer.Enabled = false;
HoverState.Timer.Interval = HoverState.Interval;
HoverState.Timer.Tick += new EventHandler(MouseHover);
HoverState.Size = new Size(4, 4);
HoverState.X = -1;
HoverState.Y = -1;
ActiveWindow = IntPtr.Zero;
FocusWindow = IntPtr.Zero;
ModalWindows = new Stack(3);
MouseState = MouseButtons.None;
mouse_position = new Point(0, 0);
Caret.Timer = new Timer();
Caret.Timer.Interval = 500; // FIXME - where should this number come from?
Caret.Timer.Tick += new EventHandler(CaretCallback);
SetupAtoms();
// Grab atom changes off the root window to catch certain WM events
XSelectInput(DisplayHandle, RootWindow, new IntPtr ((int) (EventMask.PropertyChangeMask | Keyboard.KeyEventMask)));
// Handle any upcoming errors
ErrorHandler = new XErrorHandler(HandleError);
XSetErrorHandler(ErrorHandler);
} else {
throw new ArgumentNullException("Display", "Could not open display (X-Server required. Check you DISPLAY environment variable)");
}
}
#endregion // Internal Methods