Added SDL_SetWindowBordered() API.

--HG--
extra : rebase_source : 11750f0d8e7b59af26d97c778a332c0b4b72ea4b
This commit is contained in:
Ryan C. Gordon 2012-09-13 01:43:53 -04:00
parent 546d0f18a2
commit 8835a0dacb
21 changed files with 159 additions and 83 deletions

View file

@ -84,6 +84,7 @@ typedef struct
* \sa SDL_SetWindowIcon()
* \sa SDL_SetWindowPosition()
* \sa SDL_SetWindowSize()
* \sa SDL_SetWindowBorder()
* \sa SDL_SetWindowTitle()
* \sa SDL_ShowWindow()
*/
@ -517,6 +518,23 @@ extern DECLSPEC void SDLCALL SDL_SetWindowSize(SDL_Window * window, int w,
extern DECLSPEC void SDLCALL SDL_GetWindowSize(SDL_Window * window, int *w,
int *h);
/**
* \brief Set the border state of a window.
*
* This will add or remove the window's SDL_WINDOW_BORDERLESS flag and
* add or remove the border from the actual window. This is a no-op if the
* window's border already matches the requested state.
*
* \param window The window of which to change the border state.
* \param bordered SDL_FALSE to remove border, SDL_TRUE to add border.
*
* \note You can't change the border state of a fullscreen window.
*
* \sa SDL_GetWindowFlags()
*/
extern DECLSPEC void SDLCALL SDL_SetWindowBordered(SDL_Window * window,
SDL_bool bordered);
/**
* \brief Show a window.
*

View file

@ -186,6 +186,7 @@ struct SDL_VideoDevice
void (*MaximizeWindow) (_THIS, SDL_Window * window);
void (*MinimizeWindow) (_THIS, SDL_Window * window);
void (*RestoreWindow) (_THIS, SDL_Window * window);
void (*SetWindowBordered) (_THIS, SDL_Window * window, SDL_bool bordered);
void (*SetWindowFullscreen) (_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
int (*SetWindowGammaRamp) (_THIS, SDL_Window * window, const Uint16 * ramp);
int (*GetWindowGammaRamp) (_THIS, SDL_Window * window, Uint16 * ramp);

View file

@ -1490,6 +1490,24 @@ SDL_GetWindowPosition(SDL_Window * window, int *x, int *y)
}
}
void
SDL_SetWindowBordered(SDL_Window * window, SDL_bool bordered)
{
CHECK_WINDOW_MAGIC(window, );
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
const int want = (bordered != SDL_FALSE); /* normalize the flag. */
const int have = ((window->flags & SDL_WINDOW_BORDERLESS) == 0);
if ((want != have) && (_this->SetWindowBordered)) {
if (want) {
window->flags &= ~SDL_WINDOW_BORDERLESS;
} else {
window->flags |= SDL_WINDOW_BORDERLESS;
}
_this->SetWindowBordered(_this, window, (SDL_bool) want);
}
}
}
void
SDL_SetWindowSize(SDL_Window * window, int w, int h)
{

View file

@ -55,6 +55,7 @@ enum WinCommands {
BWIN_MINIMIZE_WINDOW,
BWIN_RESTORE_WINDOW,
BWIN_SET_TITLE,
BWIN_SET_BORDERED,
BWIN_FULLSCREEN
};
@ -372,6 +373,9 @@ class SDL_BWin:public BDirectWindow
case BWIN_RESIZE_WINDOW:
_ResizeTo(message);
break;
case BWIN_SET_BORDERED:
_SetBordered(message);
break;
case BWIN_SHOW_WINDOW:
Show();
break;
@ -553,7 +557,15 @@ private:
}
ResizeTo(w, h);
}
void _SetBordered(BMessage *msg) {
bool bEnabled;
if(msg->FindInt32("window-border", &bEnabled) != B_OK) {
return;
}
SetLook(bEnabled ? B_BORDERED_WINDOW_LOOK : B_NO_BORDER_WINDOW_LOOK);
}
void _Restore() {
if(IsMinimized()) {
Minimize(false);

View file

@ -80,6 +80,7 @@ BE_CreateDevice(int devindex)
device->MaximizeWindow = BE_MaximizeWindow;
device->MinimizeWindow = BE_MinimizeWindow;
device->RestoreWindow = BE_RestoreWindow;
device->SetWindowBordered = BE_SetWindowBordered;
device->SetWindowFullscreen = BE_SetWindowFullscreen;
device->SetWindowGammaRamp = BE_SetWindowGammaRamp;
device->GetWindowGammaRamp = BE_GetWindowGammaRamp;

View file

@ -139,6 +139,12 @@ void BE_SetWindowSize(_THIS, SDL_Window * window) {
_ToBeWin(window)->PostMessage(&msg);
}
void BE_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) {
BMessage msg(BWIN_SET_BORDERED);
msg.AddBool("window-border", bordered != SDL_FALSE);
_ToBeWin(window)->PostMessage(&msg);
}
void BE_ShowWindow(_THIS, SDL_Window * window) {
BMessage msg(BWIN_SHOW_WINDOW);
_ToBeWin(window)->PostMessage(&msg);

View file

@ -38,6 +38,7 @@ extern void BE_RaiseWindow(_THIS, SDL_Window * window);
extern void BE_MaximizeWindow(_THIS, SDL_Window * window);
extern void BE_MinimizeWindow(_THIS, SDL_Window * window);
extern void BE_RestoreWindow(_THIS, SDL_Window * window);
extern void BE_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered);
extern void BE_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
extern int BE_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp);
extern int BE_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp);

View file

@ -100,6 +100,7 @@ Cocoa_CreateDevice(int devindex)
device->MaximizeWindow = Cocoa_MaximizeWindow;
device->MinimizeWindow = Cocoa_MinimizeWindow;
device->RestoreWindow = Cocoa_RestoreWindow;
device->SetWindowFullscreen = Cocoa_SetWindowBordered;
device->SetWindowFullscreen = Cocoa_SetWindowFullscreen;
device->SetWindowGammaRamp = Cocoa_SetWindowGammaRamp;
device->GetWindowGammaRamp = Cocoa_GetWindowGammaRamp;

View file

@ -102,6 +102,7 @@ extern void Cocoa_RaiseWindow(_THIS, SDL_Window * window);
extern void Cocoa_MaximizeWindow(_THIS, SDL_Window * window);
extern void Cocoa_MinimizeWindow(_THIS, SDL_Window * window);
extern void Cocoa_RestoreWindow(_THIS, SDL_Window * window);
extern void Cocoa_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered);
extern void Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
extern int Cocoa_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp);
extern int Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp);

View file

@ -821,6 +821,20 @@ Cocoa_RebuildWindow(SDL_WindowData * data, NSWindow * nswindow, unsigned style)
return data->nswindow;
}
void
Cocoa_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
{
/* this message arrived in 10.6. You're out of luck on older OSes. */
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
if ([nswindow respondsToSelector:@selector(setStyleMask:)]) {
[nswindow setStyleMask:GetWindowStyle(window)];
}
[pool release];
#endif
}
void
Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
{

View file

@ -132,6 +132,8 @@ DirectFB_CreateDevice(int devindex)
device->DestroyWindow = DirectFB_DestroyWindow;
device->GetWindowWMInfo = DirectFB_GetWindowWMInfo;
/* !!! FIXME: implement SetWindowBordered */
#if SDL_DIRECTFB_OPENGL
device->GL_LoadLibrary = DirectFB_GL_LoadLibrary;
device->GL_GetProcAddress = DirectFB_GL_GetProcAddress;

View file

@ -131,6 +131,8 @@ PND_create()
device->GL_DeleteContext = PND_gl_deletecontext;
device->PumpEvents = PND_PumpEvents;
/* !!! FIXME: implement SetWindowBordered */
return device;
}

View file

@ -90,6 +90,8 @@ UIKit_CreateDevice(int devindex)
device->DestroyWindow = UIKit_DestroyWindow;
device->GetWindowWMInfo = UIKit_GetWindowWMInfo;
/* !!! FIXME: implement SetWindowBordered */
device->SDL_HasScreenKeyboardSupport = UIKit_HasScreenKeyboardSupport;
device->SDL_ShowScreenKeyboard = UIKit_ShowScreenKeyboard;
device->SDL_HideScreenKeyboard = UIKit_HideScreenKeyboard;

View file

@ -125,6 +125,7 @@ WIN_CreateDevice(int devindex)
device->MaximizeWindow = WIN_MaximizeWindow;
device->MinimizeWindow = WIN_MinimizeWindow;
device->RestoreWindow = WIN_RestoreWindow;
device->SetWindowBordered = WIN_SetWindowBordered;
device->SetWindowFullscreen = WIN_SetWindowFullscreen;
device->SetWindowGammaRamp = WIN_SetWindowGammaRamp;
device->GetWindowGammaRamp = WIN_GetWindowGammaRamp;

View file

@ -504,6 +504,13 @@ WIN_MinimizeWindow(_THIS, SDL_Window * window)
#endif
}
void
WIN_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
{
HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
SetWindowLong(hwnd, GWL_STYLE, GetWindowStyle(window));
}
void
WIN_RestoreWindow(_THIS, SDL_Window * window)
{

View file

@ -57,6 +57,7 @@ extern void WIN_RaiseWindow(_THIS, SDL_Window * window);
extern void WIN_MaximizeWindow(_THIS, SDL_Window * window);
extern void WIN_MinimizeWindow(_THIS, SDL_Window * window);
extern void WIN_RestoreWindow(_THIS, SDL_Window * window);
extern void WIN_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered);
extern void WIN_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
extern int WIN_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp);
extern int WIN_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp);

View file

@ -27,6 +27,7 @@ SDL_X11_SYM(int,XAutoRepeatOn,(Display* a),(a),return)
SDL_X11_SYM(int,XAutoRepeatOff,(Display* a),(a),return)
SDL_X11_SYM(int,XChangePointerControl,(Display* a,Bool b,Bool c,int d,int e,int f),(a,b,c,d,e,f),return)
SDL_X11_SYM(int,XChangeProperty,(Display* a,Window b,Atom c,Atom d,int e,int f,_Xconst unsigned char* g,int h),(a,b,c,d,e,f,g,h),return)
SDL_X11_SYM(Bool,XCheckIfEvent,(Display* a,XEvent *b,Bool (*c)(Display*,XEvent*,XPointer),XPointer d),(a,b,c,d),return)
SDL_X11_SYM(int,XCloseDisplay,(Display* a),(a),return)
SDL_X11_SYM(int,XConvertSelection,(Display* a,Atom b,Atom c,Atom d,Window e,Time f),(a,b,c,d,e,f),return)
SDL_X11_SYM(Pixmap,XCreateBitmapFromData,(Display *dpy,Drawable d,_Xconst char *data,unsigned int width,unsigned int height),(dpy,d,data,width,height),return)

View file

@ -194,6 +194,7 @@ X11_CreateDevice(int devindex)
device->MaximizeWindow = X11_MaximizeWindow;
device->MinimizeWindow = X11_MinimizeWindow;
device->RestoreWindow = X11_RestoreWindow;
device->SetWindowBordered = X11_SetWindowBordered;
device->SetWindowFullscreen = X11_SetWindowFullscreen;
device->SetWindowGammaRamp = X11_SetWindowGammaRamp;
device->SetWindowGrab = X11_SetWindowGrab;

View file

@ -247,6 +247,37 @@ SetupWindowData(_THIS, SDL_Window * window, Window w, BOOL created)
return 0;
}
static void
SetWindowBordered(Display *display, int screen, Window window, SDL_bool border)
{
/*
* this code used to check for KWM_WIN_DECORATION, but KDE hasn't
* supported it for years and years. It now respects _MOTIF_WM_HINTS.
* Gnome is similar: just use the Motif atom.
*/
Atom WM_HINTS = XInternAtom(display, "_MOTIF_WM_HINTS", True);
if (WM_HINTS != None) {
/* Hints used by Motif compliant window managers */
struct
{
unsigned long flags;
unsigned long functions;
unsigned long decorations;
long input_mode;
unsigned long status;
} MWMHints = {
(1L << 1), 0, border ? 1 : 0, 0, 0
};
XChangeProperty(display, window, WM_HINTS, WM_HINTS, 32,
PropModeReplace, (unsigned char *) &MWMHints,
sizeof(MWMHints) / 4);
} else { /* set the transient hints instead, if necessary */
XSetTransientForHint(display, window, RootWindow(display, screen));
}
}
int
X11_CreateWindow(_THIS, SDL_Window * window)
{
@ -412,88 +443,8 @@ X11_CreateWindow(_THIS, SDL_Window * window)
}
#endif
if (window->flags & SDL_WINDOW_BORDERLESS) {
SDL_bool set;
Atom WM_HINTS;
/* We haven't modified the window manager hints yet */
set = SDL_FALSE;
/* First try to set MWM hints */
WM_HINTS = XInternAtom(display, "_MOTIF_WM_HINTS", True);
if (WM_HINTS != None) {
/* Hints used by Motif compliant window managers */
struct
{
unsigned long flags;
unsigned long functions;
unsigned long decorations;
long input_mode;
unsigned long status;
} MWMHints = {
(1L << 1), 0, 0, 0, 0};
XChangeProperty(display, w, WM_HINTS, WM_HINTS, 32,
PropModeReplace, (unsigned char *) &MWMHints,
sizeof(MWMHints) / 4);
set = SDL_TRUE;
}
/* Now try to set KWM hints */
WM_HINTS = XInternAtom(display, "KWM_WIN_DECORATION", True);
if (WM_HINTS != None) {
long KWMHints = 0;
XChangeProperty(display, w, WM_HINTS, WM_HINTS, 32,
PropModeReplace,
(unsigned char *) &KWMHints,
sizeof(KWMHints) / 4);
set = SDL_TRUE;
}
/* Now try to set GNOME hints */
WM_HINTS = XInternAtom(display, "_WIN_HINTS", True);
if (WM_HINTS != None) {
long GNOMEHints = 0;
XChangeProperty(display, w, WM_HINTS, WM_HINTS, 32,
PropModeReplace,
(unsigned char *) &GNOMEHints,
sizeof(GNOMEHints) / 4);
set = SDL_TRUE;
}
/* Finally set the transient hints if necessary */
if (!set) {
XSetTransientForHint(display, w, RootWindow(display, screen));
}
} else {
SDL_bool set;
Atom WM_HINTS;
/* We haven't modified the window manager hints yet */
set = SDL_FALSE;
/* First try to unset MWM hints */
WM_HINTS = XInternAtom(display, "_MOTIF_WM_HINTS", True);
if (WM_HINTS != None) {
XDeleteProperty(display, w, WM_HINTS);
set = SDL_TRUE;
}
/* Now try to unset KWM hints */
WM_HINTS = XInternAtom(display, "KWM_WIN_DECORATION", True);
if (WM_HINTS != None) {
XDeleteProperty(display, w, WM_HINTS);
set = SDL_TRUE;
}
/* Now try to unset GNOME hints */
WM_HINTS = XInternAtom(display, "_WIN_HINTS", True);
if (WM_HINTS != None) {
XDeleteProperty(display, w, WM_HINTS);
set = SDL_TRUE;
}
/* Finally unset the transient hints if necessary */
if (!set) {
XDeleteProperty(display, w, XA_WM_TRANSIENT_FOR);
}
}
SetWindowBordered(display, screen, w,
(window->flags & SDL_WINDOW_BORDERLESS) == 0);
/* Setup the normal size hints */
sizehints.flags = 0;
@ -775,6 +726,29 @@ static Bool isUnmapNotify(Display *dpy, XEvent *ev, XPointer win)
{
return ev->type == UnmapNotify && ev->xunmap.window == *((Window*)win);
}
static Bool isConfigureNotify(Display *dpy, XEvent *ev, XPointer win)
{
return ev->type == ConfigureNotify && ev->xunmap.window == *((Window*)win);
}
void
X11_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
{
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
SDL_DisplayData *displaydata =
(SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
Display *display = data->videodata->display;
XEvent event;
SetWindowBordered(display, displaydata->screen, data->xwindow, bordered);
XIfEvent(display, &event, &isConfigureNotify, (XPointer)&data->xwindow);
/* make sure these don't make it to the real event queue if they fired here. */
while (XCheckIfEvent(display, &event, &isMapNotify, (XPointer)&data->xwindow)) {}
while (XCheckIfEvent(display, &event, &isUnmapNotify, (XPointer)&data->xwindow)) {}
XFlush(display);
}
void
X11_ShowWindow(_THIS, SDL_Window * window)

View file

@ -54,6 +54,7 @@ extern void X11_RaiseWindow(_THIS, SDL_Window * window);
extern void X11_MaximizeWindow(_THIS, SDL_Window * window);
extern void X11_MinimizeWindow(_THIS, SDL_Window * window);
extern void X11_RestoreWindow(_THIS, SDL_Window * window);
extern void X11_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered);
extern void X11_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
extern int X11_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp);
extern void X11_SetWindowGrab(_THIS, SDL_Window * window);

View file

@ -1142,6 +1142,17 @@ CommonEvent(CommonState * state, SDL_Event * event, int *done)
}
}
break;
case SDLK_b:
if (event->key.keysym.mod & KMOD_CTRL) {
/* Ctrl-B toggle window border */
SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
if (window) {
const Uint32 flags = SDL_GetWindowFlags(window);
const SDL_bool b = ((flags & SDL_WINDOW_BORDERLESS) != 0);
SDL_SetWindowBordered(window, b);
}
}
break;
case SDLK_ESCAPE:
*done = 1;
break;