Fixed regression from conflict resolution.

This commit is contained in:
the_fiddler 2008-05-04 16:10:53 +00:00
parent bf8a11f103
commit 6d470e90a8

View file

@ -20,7 +20,7 @@ using OpenTK.Graphics;
//using OpenTK.Graphics.OpenGL; //using OpenTK.Graphics.OpenGL;
namespace OpenTK.Platform.X11 namespace OpenTK.Platform.X11
{ {
/// <summary> /// <summary>
/// Drives GameWindow on X11. /// Drives GameWindow on X11.
/// This class supports OpenTK, and is not intended for use by OpenTK programs. /// This class supports OpenTK, and is not intended for use by OpenTK programs.
@ -32,42 +32,42 @@ namespace OpenTK.Platform.X11
// TODO: Mouse/keyboard grabbing/wrapping. // TODO: Mouse/keyboard grabbing/wrapping.
// TODO: PointToWindow, PointToScreen // TODO: PointToWindow, PointToScreen
#region --- Fields --- #region --- Fields ---
const int _min_width = 30, _min_height = 30; const int _min_width = 30, _min_height = 30;
X11WindowInfo window = new X11WindowInfo(); X11WindowInfo window = new X11WindowInfo();
X11Input driver; X11Input driver;
// Window manager hints for fullscreen windows. // Window manager hints for fullscreen windows.
// Not used right now (the code is written, but is not 64bit-correct), but could be useful for older WMs which // Not used right now (the code is written, but is not 64bit-correct), but could be useful for older WMs which
// are not ICCM compliant, but may support MOTIF hints. // are not ICCM compliant, but may support MOTIF hints.
const string MOTIF_WM_ATOM = "_MOTIF_WM_HINTS"; const string MOTIF_WM_ATOM = "_MOTIF_WM_HINTS";
const string KDE_WM_ATOM = "KWM_WIN_DECORATION"; const string KDE_WM_ATOM = "KWM_WIN_DECORATION";
const string KDE_NET_WM_ATOM = "_KDE_NET_WM_WINDOW_TYPE"; const string KDE_NET_WM_ATOM = "_KDE_NET_WM_WINDOW_TYPE";
const string ICCM_WM_ATOM = "_NET_WM_WINDOW_TYPE"; const string ICCM_WM_ATOM = "_NET_WM_WINDOW_TYPE";
// The Atom class from Mono might be useful to avoid calling XInternAtom by hand (somewhat error prone). // The Atom class from Mono might be useful to avoid calling XInternAtom by hand (somewhat error prone).
IntPtr _atom_wm_destroy; IntPtr _atom_wm_destroy;
IntPtr _atom_net_wm_state; IntPtr _atom_net_wm_state;
IntPtr _atom_net_wm_state_minimized; IntPtr _atom_net_wm_state_minimized;
IntPtr _atom_net_wm_state_fullscreen; IntPtr _atom_net_wm_state_fullscreen;
IntPtr _atom_net_wm_state_maximized_horizontal; IntPtr _atom_net_wm_state_maximized_horizontal;
IntPtr _atom_net_wm_state_maximized_vertical; IntPtr _atom_net_wm_state_maximized_vertical;
IntPtr _atom_net_wm_allowed_actions; IntPtr _atom_net_wm_allowed_actions;
IntPtr _atom_net_wm_action_resize; IntPtr _atom_net_wm_action_resize;
IntPtr _atom_net_wm_action_maximize_horizontally; IntPtr _atom_net_wm_action_maximize_horizontally;
IntPtr _atom_net_wm_action_maximize_vertically; IntPtr _atom_net_wm_action_maximize_vertically;
IntPtr _atom_motif_wm_hints; IntPtr _atom_motif_wm_hints;
IntPtr _atom_kde_wm_hints; IntPtr _atom_kde_wm_hints;
IntPtr _atom_kde_net_wm_hints; IntPtr _atom_kde_net_wm_hints;
static readonly IntPtr _atom_remove = (IntPtr)0; static readonly IntPtr _atom_remove = (IntPtr)0;
static readonly IntPtr _atom_add = (IntPtr)1; static readonly IntPtr _atom_add = (IntPtr)1;
static readonly IntPtr _atom_toggle = (IntPtr)2; static readonly IntPtr _atom_toggle = (IntPtr)2;
// Number of pending events. // Number of pending events.
int pending = 0; int pending = 0;
@ -91,11 +91,11 @@ namespace OpenTK.Platform.X11
// Fields used for fullscreen mode changes. // Fields used for fullscreen mode changes.
int pre_fullscreen_width, pre_fullscreen_height; int pre_fullscreen_width, pre_fullscreen_height;
//bool fullscreen = false; //bool fullscreen = false;
bool _decorations_hidden = false; bool _decorations_hidden = false;
//OpenTK.WindowState _window_state, _previous_window_state; //OpenTK.WindowState _window_state, _previous_window_state;
//OpenTK.WindowBorder _window_border, _previous_window_border; //OpenTK.WindowBorder _window_border, _previous_window_border;
#endregion #endregion
@ -141,9 +141,9 @@ namespace OpenTK.Platform.X11
Functions.XUnlockDisplay(window.Display); Functions.XUnlockDisplay(window.Display);
} }
Debug.Print("Display: {0}, Screen {1}, Root window: {2}", window.Display, window.Screen, Debug.Print("Display: {0}, Screen {1}, Root window: {2}", window.Display, window.Screen,
window.RootWindow); window.RootWindow);
RegisterAtoms(window); RegisterAtoms(window);
} }
finally finally
@ -161,31 +161,31 @@ namespace OpenTK.Platform.X11
/// Registers the necessary atoms for GameWindow. /// Registers the necessary atoms for GameWindow.
/// </summary> /// </summary>
private void RegisterAtoms(X11WindowInfo window) private void RegisterAtoms(X11WindowInfo window)
{ {
Debug.WriteLine("Registering atoms."); Debug.WriteLine("Registering atoms.");
_atom_wm_destroy = Functions.XInternAtom(window.Display, "WM_DELETE_WINDOW", true); _atom_wm_destroy = Functions.XInternAtom(window.Display, "WM_DELETE_WINDOW", true);
_atom_net_wm_state = Functions.XInternAtom(window.Display, "_NET_WM_STATE", false); _atom_net_wm_state = Functions.XInternAtom(window.Display, "_NET_WM_STATE", false);
_atom_net_wm_state_minimized = Functions.XInternAtom(window.Display, "_NET_WM_STATE_MINIMIZED", false); _atom_net_wm_state_minimized = Functions.XInternAtom(window.Display, "_NET_WM_STATE_MINIMIZED", false);
_atom_net_wm_state_fullscreen = Functions.XInternAtom(window.Display, "_NET_WM_STATE_FULLSCREEN", false); _atom_net_wm_state_fullscreen = Functions.XInternAtom(window.Display, "_NET_WM_STATE_FULLSCREEN", false);
_atom_net_wm_state_maximized_horizontal = _atom_net_wm_state_maximized_horizontal =
Functions.XInternAtom(window.Display, "_NET_WM_STATE_MAXIMIZED_HORZ", false); Functions.XInternAtom(window.Display, "_NET_WM_STATE_MAXIMIZED_HORZ", false);
_atom_net_wm_state_maximized_vertical = _atom_net_wm_state_maximized_vertical =
Functions.XInternAtom(window.Display, "_NET_WM_STATE_MAXIMIZED_VERT", false); Functions.XInternAtom(window.Display, "_NET_WM_STATE_MAXIMIZED_VERT", false);
_atom_net_wm_allowed_actions = _atom_net_wm_allowed_actions =
Functions.XInternAtom(window.Display, "_NET_WM_ALLOWED_ACTIONS", false); Functions.XInternAtom(window.Display, "_NET_WM_ALLOWED_ACTIONS", false);
_atom_net_wm_action_resize = _atom_net_wm_action_resize =
Functions.XInternAtom(window.Display, "_NET_WM_ACTION_RESIZE", false); Functions.XInternAtom(window.Display, "_NET_WM_ACTION_RESIZE", false);
_atom_net_wm_action_maximize_horizontally = _atom_net_wm_action_maximize_horizontally =
Functions.XInternAtom(window.Display, "_NET_WM_ACTION_MAXIMIZE_HORZ", false); Functions.XInternAtom(window.Display, "_NET_WM_ACTION_MAXIMIZE_HORZ", false);
_atom_net_wm_action_maximize_vertically = _atom_net_wm_action_maximize_vertically =
Functions.XInternAtom(window.Display, "_NET_WM_ACTION_MAXIMIZE_VERT", false); Functions.XInternAtom(window.Display, "_NET_WM_ACTION_MAXIMIZE_VERT", false);
// string[] atom_names = new string[] // string[] atom_names = new string[]
// { // {
// //"WM_TITLE", // //"WM_TITLE",
// //"UTF8_STRING" // //"UTF8_STRING"
// }; // };
// IntPtr[] atoms = new IntPtr[atom_names.Length]; // IntPtr[] atoms = new IntPtr[atom_names.Length];
// //Functions.XInternAtoms(window.Display, atom_names, atom_names.Length, false, atoms); // //Functions.XInternAtoms(window.Display, atom_names, atom_names.Length, false, atoms);
@ -246,8 +246,8 @@ namespace OpenTK.Platform.X11
} }
context = new GraphicsContext(mode, window); context = new GraphicsContext(mode, window);
// Set the window hints // Set the window hints
SetWindowMinMax(_min_width, _min_height, -1, -1); SetWindowMinMax(_min_width, _min_height, -1, -1);
XSizeHints hints = new XSizeHints(); XSizeHints hints = new XSizeHints();
hints.x = 0; hints.x = 0;
@ -282,22 +282,22 @@ namespace OpenTK.Platform.X11
//context.CreateContext(true, null); //context.CreateContext(true, null);
driver = new X11Input(window); driver = new X11Input(window);
// HACK: This seems to reduce thread issues on Linux, due to race conditions. // HACK: This seems to reduce thread issues on Linux, due to race conditions.
// It does *not* solve the root cause, which is unknown at this point. // It does *not* solve the root cause, which is unknown at this point.
// //
// What I suspect happens, is that either the glXChooseContext or glXCreateContext functions are called // What I suspect happens, is that either the glXChooseContext or glXCreateContext functions are called
// before the window is ready - or maybe before the window size is set which renders the viewport invalid? // before the window is ready - or maybe before the window size is set which renders the viewport invalid?
// (can this happen?) or that there are pending events that somehow botch context creation up (seems like // (can this happen?) or that there are pending events that somehow botch context creation up (seems like
// the fglrx driver is spawning a new thread, or waiting on something?) // the fglrx driver is spawning a new thread, or waiting on something?)
// This issue *must* be resolved before the 1.0 release. // This issue *must* be resolved before the 1.0 release.
// Note that this has the side effect that sometimes, a resize event is missed. // Note that this has the side effect that sometimes, a resize event is missed.
//Functions.XSync(window.Display, true); //Functions.XSync(window.Display, true);
Debug.WriteLine("X11GLNative window created successfully!"); Debug.WriteLine("X11GLNative window created successfully!");
Debug.Unindent(); Debug.Unindent();
exists = true; exists = true;
} }
@ -333,12 +333,12 @@ namespace OpenTK.Platform.X11
// A child was was created - nothing to do // A child was was created - nothing to do
break; break;
case XEventName.ClientMessage: case XEventName.ClientMessage:
if (e.ClientMessageEvent.ptr1 == _atom_wm_destroy) if (e.ClientMessageEvent.ptr1 == _atom_wm_destroy)
this.OnDestroy(EventArgs.Empty); this.OnDestroy(EventArgs.Empty);
else else
Debug.Print("Niar"); Debug.Print("Niar");
break; break;
@ -426,7 +426,7 @@ namespace OpenTK.Platform.X11
public bool Fullscreen public bool Fullscreen
{ {
get get
{ {
return false; return false;
//return fullscreen; //return fullscreen;
} }
@ -436,7 +436,7 @@ namespace OpenTK.Platform.X11
// { // {
// Debug.Print("Going fullscreen"); // Debug.Print("Going fullscreen");
// Debug.Indent(); // Debug.Indent();
// DisableWindowDecorations(); // DisableWindowDecorations();
// pre_fullscreen_height = this.Height; // pre_fullscreen_height = this.Height;
// pre_fullscreen_width = this.Width; // pre_fullscreen_width = this.Width;
// //Functions.XRaiseWindow(this.window.Display, this.Handle); // //Functions.XRaiseWindow(this.window.Display, this.Handle);
@ -640,117 +640,117 @@ namespace OpenTK.Platform.X11
{ {
get get
{ {
IntPtr actual_atom; IntPtr actual_atom;
int actual_format; int actual_format;
IntPtr nitems; IntPtr nitems;
IntPtr bytes_after; IntPtr bytes_after;
IntPtr prop = IntPtr.Zero; IntPtr prop = IntPtr.Zero;
IntPtr atom; IntPtr atom;
XWindowAttributes attributes; XWindowAttributes attributes;
bool fullscreen = false; bool fullscreen = false;
int maximized = 0; int maximized = 0;
bool minimized = false; bool minimized = false;
Functions.XGetWindowProperty(window.Display, window.WindowHandle, Functions.XGetWindowProperty(window.Display, window.WindowHandle,
_atom_net_wm_state, IntPtr.Zero, new IntPtr (256), false, _atom_net_wm_state, IntPtr.Zero, new IntPtr (256), false,
IntPtr.Zero, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop); IntPtr.Zero, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
if ((long)nitems > 0 && prop != IntPtr.Zero) if ((long)nitems > 0 && prop != IntPtr.Zero)
{ {
for (int i = 0; i < (long)nitems; i++) for (int i = 0; i < (long)nitems; i++)
{ {
atom = (IntPtr)Marshal.ReadIntPtr(prop, i * IntPtr.Size); atom = (IntPtr)Marshal.ReadIntPtr(prop, i * IntPtr.Size);
if (atom == _atom_net_wm_state_maximized_horizontal || if (atom == _atom_net_wm_state_maximized_horizontal ||
atom == _atom_net_wm_state_maximized_vertical) atom == _atom_net_wm_state_maximized_vertical)
maximized++; maximized++;
else if (atom == _atom_net_wm_state_minimized) else if (atom == _atom_net_wm_state_minimized)
minimized = true; minimized = true;
else if (atom == _atom_net_wm_state_fullscreen) else if (atom == _atom_net_wm_state_fullscreen)
fullscreen = true; fullscreen = true;
} }
Functions.XFree(prop); Functions.XFree(prop);
} }
if (minimized) if (minimized)
return WindowState.Minimized; return OpenTK.WindowState.Minimized;
else if (maximized == 2) else if (maximized == 2)
return OpenTK.WindowState.Maximized; return OpenTK.WindowState.Maximized;
else if (fullscreen) else if (fullscreen)
return OpenTK.WindowState.Fullscreen; return OpenTK.WindowState.Fullscreen;
/* /*
attributes = new XWindowAttributes(); attributes = new XWindowAttributes();
Functions.XGetWindowAttributes(window.Display, window.WindowHandle, ref attributes); Functions.XGetWindowAttributes(window.Display, window.WindowHandle, ref attributes);
if (attributes.map_state == MapState.IsUnmapped) if (attributes.map_state == MapState.IsUnmapped)
return (OpenTK.WindowState)(-1); return (OpenTK.WindowState)(-1);
*/ */
return OpenTK.WindowState.Normal; return OpenTK.WindowState.Normal;
} }
set set
{ {
OpenTK.WindowState current_state = this.WindowState; OpenTK.WindowState current_state = this.WindowState;
if (current_state == value) if (current_state == value)
return; return;
Debug.Print("GameWindow {0} changing WindowState from {1} to {2}.", window.WindowHandle.ToString(), Debug.Print("GameWindow {0} changing WindowState from {1} to {2}.", window.WindowHandle.ToString(),
current_state.ToString(), value.ToString()); current_state.ToString(), value.ToString());
if (current_state == OpenTK.WindowState.Minimized) if (current_state == OpenTK.WindowState.Minimized)
Functions.XMapWindow(window.Display, window.WindowHandle); Functions.XMapWindow(window.Display, window.WindowHandle);
else if (current_state == OpenTK.WindowState.Fullscreen) else if (current_state == OpenTK.WindowState.Fullscreen)
Functions.SendNetWMMessage(window, _atom_net_wm_state, _atom_remove, Functions.SendNetWMMessage(window, _atom_net_wm_state, _atom_remove,
_atom_net_wm_state_fullscreen, _atom_net_wm_state_fullscreen,
IntPtr.Zero); IntPtr.Zero);
else if (current_state == OpenTK.WindowState.Maximized) else if (current_state == OpenTK.WindowState.Maximized)
Functions.SendNetWMMessage(window, _atom_net_wm_state, _atom_toggle, Functions.SendNetWMMessage(window, _atom_net_wm_state, _atom_toggle,
_atom_net_wm_state_maximized_horizontal, _atom_net_wm_state_maximized_horizontal,
_atom_net_wm_state_maximized_vertical); _atom_net_wm_state_maximized_vertical);
Functions.XSync(window.Display, false); Functions.XSync(window.Display, false);
// We can't resize the window if its border is fixed, so make it resizable first. // We can't resize the window if its border is fixed, so make it resizable first.
bool temporary_resizable = false; bool temporary_resizable = false;
WindowBorder previous_state = WindowBorder; WindowBorder previous_state = WindowBorder;
if (WindowBorder != WindowBorder.Resizable) if (WindowBorder != WindowBorder.Resizable)
{ {
temporary_resizable = true; temporary_resizable = true;
WindowBorder = WindowBorder.Resizable; WindowBorder = WindowBorder.Resizable;
} }
switch (value) switch (value)
{ {
case OpenTK.WindowState.Normal: case OpenTK.WindowState.Normal:
Functions.XRaiseWindow(window.Display, window.WindowHandle); Functions.XRaiseWindow(window.Display, window.WindowHandle);
break; break;
case OpenTK.WindowState.Maximized: case OpenTK.WindowState.Maximized:
Functions.SendNetWMMessage(window, _atom_net_wm_state, _atom_add, Functions.SendNetWMMessage(window, _atom_net_wm_state, _atom_add,
_atom_net_wm_state_maximized_horizontal, _atom_net_wm_state_maximized_horizontal,
_atom_net_wm_state_maximized_vertical); _atom_net_wm_state_maximized_vertical);
Functions.XRaiseWindow(window.Display, window.WindowHandle); Functions.XRaiseWindow(window.Display, window.WindowHandle);
break; break;
case WindowState.Minimized: case OpenTK.WindowState.Minimized:
// FIXME multiscreen support // FIXME multiscreen support
Functions.XIconifyWindow(window.Display, window.WindowHandle, window.Screen); Functions.XIconifyWindow(window.Display, window.WindowHandle, window.Screen);
break; break;
case WindowState.Fullscreen: case OpenTK.WindowState.Fullscreen:
//_previous_window_border = this.WindowBorder; //_previous_window_border = this.WindowBorder;
//this.WindowBorder = WindowBorder.Hidden; //this.WindowBorder = WindowBorder.Hidden;
Functions.SendNetWMMessage(window, _atom_net_wm_state, _atom_add, Functions.SendNetWMMessage(window, _atom_net_wm_state, _atom_add,
_atom_net_wm_state_fullscreen, IntPtr.Zero); _atom_net_wm_state_fullscreen, IntPtr.Zero);
Functions.XRaiseWindow(window.Display, window.WindowHandle); Functions.XRaiseWindow(window.Display, window.WindowHandle);
break; break;
} }
if (temporary_resizable) if (temporary_resizable)
WindowBorder = previous_state; WindowBorder = previous_state;
} }
} }
@ -762,82 +762,82 @@ namespace OpenTK.Platform.X11
{ {
get get
{ {
if (IsWindowBorderHidden) if (IsWindowBorderHidden)
return WindowBorder.Hidden; return WindowBorder.Hidden;
if (IsWindowBorderResizable) if (IsWindowBorderResizable)
return WindowBorder.Resizable; return WindowBorder.Resizable;
else else
return WindowBorder.Fixed; return WindowBorder.Fixed;
} }
set set
{ {
if (WindowBorder == value) if (WindowBorder == value)
return; return;
if (WindowBorder == WindowBorder.Hidden) if (WindowBorder == WindowBorder.Hidden)
EnableWindowDecorations(); EnableWindowDecorations();
switch (value) switch (value)
{ {
case WindowBorder.Fixed: case WindowBorder.Fixed:
Debug.Print("Making WindowBorder fixed."); Debug.Print("Making WindowBorder fixed.");
SetWindowMinMax((short)Width, (short)Height, (short)Width, (short)Height); SetWindowMinMax((short)Width, (short)Height, (short)Width, (short)Height);
break; break;
case WindowBorder.Resizable: case WindowBorder.Resizable:
Debug.Print("Making WindowBorder resizable."); Debug.Print("Making WindowBorder resizable.");
SetWindowMinMax(_min_width, _min_height, -1, -1); SetWindowMinMax(_min_width, _min_height, -1, -1);
break; break;
case WindowBorder.Hidden: case WindowBorder.Hidden:
Debug.Print("Making WindowBorder hidden."); Debug.Print("Making WindowBorder hidden.");
DisableWindowDecorations(); DisableWindowDecorations();
break; break;
} }
} }
} }
#endregion #endregion
#endregion #endregion
void SetWindowMinMax(short min_width, short min_height, short max_width, short max_height) void SetWindowMinMax(short min_width, short min_height, short max_width, short max_height)
{ {
IntPtr dummy; IntPtr dummy;
XSizeHints hints = new XSizeHints(); XSizeHints hints = new XSizeHints();
Functions.XGetWMNormalHints(window.Display, window.WindowHandle, ref hints, out dummy); Functions.XGetWMNormalHints(window.Display, window.WindowHandle, ref hints, out dummy);
if (min_width > 0 || min_height > 0) if (min_width > 0 || min_height > 0)
{ {
hints.flags = (IntPtr)((int)hints.flags | (int)XSizeHintsFlags.PMinSize); hints.flags = (IntPtr)((int)hints.flags | (int)XSizeHintsFlags.PMinSize);
hints.min_width = min_width; hints.min_width = min_width;
hints.min_height = min_height; hints.min_height = min_height;
} }
else else
hints.flags = (IntPtr)((int)hints.flags & ~(int)XSizeHintsFlags.PMinSize); hints.flags = (IntPtr)((int)hints.flags & ~(int)XSizeHintsFlags.PMinSize);
if (max_width > 0 || max_height > 0) if (max_width > 0 || max_height > 0)
{ {
hints.flags = (IntPtr)((int)hints.flags | (int)XSizeHintsFlags.PMaxSize); hints.flags = (IntPtr)((int)hints.flags | (int)XSizeHintsFlags.PMaxSize);
hints.max_width = max_width; hints.max_width = max_width;
hints.max_height = max_height; hints.max_height = max_height;
} }
else else
hints.flags = (IntPtr)((int)hints.flags & ~(int)XSizeHintsFlags.PMaxSize); hints.flags = (IntPtr)((int)hints.flags & ~(int)XSizeHintsFlags.PMaxSize);
if (hints.flags != IntPtr.Zero) if (hints.flags != IntPtr.Zero)
{ {
// The Metacity team has decided that they won't care about this when clicking the maximize // The Metacity team has decided that they won't care about this when clicking the maximize
// icon, will maximize the window to fill the screen/parent no matter what. // icon, will maximize the window to fill the screen/parent no matter what.
// http://bugzilla.ximian.com/show_bug.cgi?id=80021 // http://bugzilla.ximian.com/show_bug.cgi?id=80021
Functions.XSetWMNormalHints(window.Display, window.WindowHandle, ref hints); Functions.XSetWMNormalHints(window.Display, window.WindowHandle, ref hints);
} }
} }
#region --- IResizable Members --- #region --- IResizable Members ---
@ -983,91 +983,91 @@ namespace OpenTK.Platform.X11
#endregion #endregion
#region --- Private Methods --- #region --- Private Methods ---
bool IsWindowBorderResizable bool IsWindowBorderResizable
{ {
get get
{ {
IntPtr actual_atom; IntPtr actual_atom;
int actual_format; int actual_format;
IntPtr nitems; IntPtr nitems;
IntPtr bytes_after; IntPtr bytes_after;
IntPtr prop = IntPtr.Zero; IntPtr prop = IntPtr.Zero;
IntPtr atom; IntPtr atom;
XWindowAttributes attributes; XWindowAttributes attributes;
Functions.XGetWindowProperty(window.Display, window.WindowHandle, Functions.XGetWindowProperty(window.Display, window.WindowHandle,
_atom_net_wm_allowed_actions, IntPtr.Zero, new IntPtr(256), false, _atom_net_wm_allowed_actions, IntPtr.Zero, new IntPtr(256), false,
IntPtr.Zero, out actual_atom, out actual_format, out nitems, IntPtr.Zero, out actual_atom, out actual_format, out nitems,
out bytes_after, ref prop); out bytes_after, ref prop);
if ((long)nitems > 0 && prop != IntPtr.Zero) if ((long)nitems > 0 && prop != IntPtr.Zero)
{ {
for (int i = 0; i < (long)nitems; i++) for (int i = 0; i < (long)nitems; i++)
{ {
atom = (IntPtr)Marshal.ReadIntPtr(prop, i * IntPtr.Size); atom = (IntPtr)Marshal.ReadIntPtr(prop, i * IntPtr.Size);
if (atom == _atom_net_wm_action_resize) if (atom == _atom_net_wm_action_resize)
return true; return true;
} }
Functions.XFree(prop); Functions.XFree(prop);
} }
return false; return false;
} }
} }
#region bool IsWindowBorderHidden #region bool IsWindowBorderHidden
bool IsWindowBorderHidden bool IsWindowBorderHidden
{ {
get get
{ {
IntPtr actual_atom; IntPtr actual_atom;
int actual_format; int actual_format;
IntPtr nitems; IntPtr nitems;
IntPtr bytes_after; IntPtr bytes_after;
IntPtr prop = IntPtr.Zero; IntPtr prop = IntPtr.Zero;
IntPtr atom; IntPtr atom;
XWindowAttributes attributes; XWindowAttributes attributes;
// Test if decorations have been disabled through Motif. // Test if decorations have been disabled through Motif.
IntPtr motif_hints_atom = Functions.XInternAtom(this.window.Display, MOTIF_WM_ATOM, true); IntPtr motif_hints_atom = Functions.XInternAtom(this.window.Display, MOTIF_WM_ATOM, true);
if (motif_hints_atom != IntPtr.Zero) if (motif_hints_atom != IntPtr.Zero)
{ {
// TODO: How to check if MotifWMHints decorations have been really disabled? // TODO: How to check if MotifWMHints decorations have been really disabled?
if (_decorations_hidden) if (_decorations_hidden)
return true; return true;
} }
// Some WMs remove decorations when the transient_for hint is set. Most new ones do not (but those // Some WMs remove decorations when the transient_for hint is set. Most new ones do not (but those
// should obey the Motif hint). Anyway, if this hint is set, we say the decorations have been remove // should obey the Motif hint). Anyway, if this hint is set, we say the decorations have been remove
// although there is a slight chance this is not the case. // although there is a slight chance this is not the case.
IntPtr transient_for_parent; IntPtr transient_for_parent;
Functions.XGetTransientForHint(window.Display, window.WindowHandle, out transient_for_parent); Functions.XGetTransientForHint(window.Display, window.WindowHandle, out transient_for_parent);
if (transient_for_parent != IntPtr.Zero) if (transient_for_parent != IntPtr.Zero)
return true; return true;
return false; return false;
} }
} }
#endregion #endregion
#region void DisableWindowDecorations() #region void DisableWindowDecorations()
void DisableWindowDecorations() void DisableWindowDecorations()
{ {
if (DisableMotifDecorations()) if (DisableMotifDecorations())
{ {
Debug.Print("Removed decorations through motif."); Debug.Print("Removed decorations through motif.");
_decorations_hidden = true; _decorations_hidden = true;
} }
// Functions.XSetTransientForHint(this.window.Display, this.Handle, this.window.RootWindow); // Functions.XSetTransientForHint(this.window.Display, this.Handle, this.window.RootWindow);
// Some WMs remove decorations when this hint is set. Doesn't hurt to try. // Some WMs remove decorations when this hint is set. Doesn't hurt to try.
Functions.XSetTransientForHint(this.window.Display, this.Handle, this.window.RootWindow); Functions.XSetTransientForHint(this.window.Display, this.Handle, this.window.RootWindow);
if (_decorations_hidden) if (_decorations_hidden)
{ {
@ -1082,12 +1082,12 @@ namespace OpenTK.Platform.X11
{ {
IntPtr atom = Functions.XInternAtom(this.window.Display, MOTIF_WM_ATOM, true); IntPtr atom = Functions.XInternAtom(this.window.Display, MOTIF_WM_ATOM, true);
if (atom != IntPtr.Zero) if (atom != IntPtr.Zero)
{ {
//Functions.XGetWindowProperty(window.Display, window.WindowHandle, atom, IntPtr.Zero, IntPtr.Zero, false, //Functions.XGetWindowProperty(window.Display, window.WindowHandle, atom, IntPtr.Zero, IntPtr.Zero, false,
MotifWmHints hints = new MotifWmHints(); MotifWmHints hints = new MotifWmHints();
hints.flags = (IntPtr)MotifFlags.Decorations; hints.flags = (IntPtr)MotifFlags.Decorations;
Functions.XChangeProperty(this.window.Display, this.Handle, atom, atom, 32, PropertyMode.Replace, Functions.XChangeProperty(this.window.Display, this.Handle, atom, atom, 32, PropertyMode.Replace,
ref hints, Marshal.SizeOf(hints) / IntPtr.Size); ref hints, Marshal.SizeOf(hints) / IntPtr.Size);
return true; return true;
} }
@ -1104,7 +1104,7 @@ namespace OpenTK.Platform.X11
if (atom != IntPtr.Zero) if (atom != IntPtr.Zero)
{ {
IntPtr hints = IntPtr.Zero; IntPtr hints = IntPtr.Zero;
Functions.XChangeProperty(this.window.Display, this.Handle, atom, atom, 32, PropertyMode.Replace, Functions.XChangeProperty(this.window.Display, this.Handle, atom, atom, 32, PropertyMode.Replace,
ref hints, Marshal.SizeOf(hints) / IntPtr.Size); ref hints, Marshal.SizeOf(hints) / IntPtr.Size);
return true; return true;
} }
@ -1119,15 +1119,15 @@ namespace OpenTK.Platform.X11
#region void EnableWindowDecorations() #region void EnableWindowDecorations()
void EnableWindowDecorations() void EnableWindowDecorations()
{ {
if (EnableMotifDecorations()) if (EnableMotifDecorations())
{ {
Debug.Print("Activated decorations through motif."); Debug.Print("Activated decorations through motif.");
_decorations_hidden = false; _decorations_hidden = false;
} }
//if (EnableGnomeDecorations()) { Debug.Print("Activated decorations through gnome."); activated = true; } //if (EnableGnomeDecorations()) { Debug.Print("Activated decorations through gnome."); activated = true; }
Functions.XSetTransientForHint(this.window.Display, this.Handle, IntPtr.Zero); Functions.XSetTransientForHint(this.window.Display, this.Handle, IntPtr.Zero);
if (!_decorations_hidden) if (!_decorations_hidden)
@ -1143,13 +1143,13 @@ namespace OpenTK.Platform.X11
{ {
IntPtr atom = Functions.XInternAtom(this.window.Display, MOTIF_WM_ATOM, true); IntPtr atom = Functions.XInternAtom(this.window.Display, MOTIF_WM_ATOM, true);
if (atom != IntPtr.Zero) if (atom != IntPtr.Zero)
{ {
//Functions.XDeleteProperty(this.window.Display, this.Handle, atom); //Functions.XDeleteProperty(this.window.Display, this.Handle, atom);
MotifWmHints hints = new MotifWmHints(); MotifWmHints hints = new MotifWmHints();
hints.flags = (IntPtr)MotifFlags.Decorations; hints.flags = (IntPtr)MotifFlags.Decorations;
hints.decorations = (IntPtr)MotifDecorations.All; hints.decorations = (IntPtr)MotifDecorations.All;
Functions.XChangeProperty(this.window.Display, this.Handle, atom, atom, 32, PropertyMode.Replace, Functions.XChangeProperty(this.window.Display, this.Handle, atom, atom, 32, PropertyMode.Replace,
ref hints, Marshal.SizeOf(hints) / IntPtr.Size); ref hints, Marshal.SizeOf(hints) / IntPtr.Size);
return true; return true;
} }