Added SDL_SetWindowOpacity() and SDL_GetWindowOpacity().
This is currently implemented for X11, Cocoa, Windows, and DirectFB. This patch is based on work in Unreal Engine 4's fork of SDL, compliments of Epic Games. --HG-- extra : amend_source : 99ddce333d2a4de7d59adb88d5059b34d731d907 extra : histedit_source : 012e8cb2f7822cd55cbbc124f642ccc530e3f75b%2Cbddf95ecf18ca97e1e3d7840971ef14ca739c9da
This commit is contained in:
parent
8afe3ca698
commit
2875d70eba
19 changed files with 174 additions and 0 deletions
|
@ -845,6 +845,34 @@ extern DECLSPEC int SDLCALL SDL_SetWindowBrightness(SDL_Window * window, float b
|
|||
*/
|
||||
extern DECLSPEC float SDLCALL SDL_GetWindowBrightness(SDL_Window * window);
|
||||
|
||||
/**
|
||||
* \brief Set the opacity for a window
|
||||
*
|
||||
* \param window The window which will be made transparent or opaque
|
||||
* \param opacity Opacity (0.0f - transparent, 1.0f - opaque) This will be
|
||||
* clamped internally between 0.0f and 1.0f.
|
||||
*
|
||||
* \return 0 on success, or -1 if setting the opacity isn't supported.
|
||||
*
|
||||
* \sa SDL_GetWindowOpacity()
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_SetWindowOpacity(SDL_Window * window, float opacity);
|
||||
|
||||
/**
|
||||
* \brief Get the opacity of a window.
|
||||
*
|
||||
* If transparency isn't supported on this platform, opacity will be reported
|
||||
* as 1.0f without error.
|
||||
*
|
||||
* \param window The window in question.
|
||||
* \param opacity Opacity (0.0f - transparent, 1.0f - opaque)
|
||||
*
|
||||
* \return 0 on success, or -1 on error (invalid window, etc).
|
||||
*
|
||||
* \sa SDL_SetWindowOpacity()
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_GetWindowOpacity(SDL_Window * window, float * out_opacity);
|
||||
|
||||
/**
|
||||
* \brief Set the gamma ramp for a window.
|
||||
*
|
||||
|
|
|
@ -599,3 +599,5 @@
|
|||
#define SDL_JoystickFromInstanceID SDL_JoystickFromInstanceID_REAL
|
||||
#define SDL_GetDisplayUsableBounds SDL_GetDisplayUsableBounds_REAL
|
||||
#define SDL_GetWindowBordersSize SDL_GetWindowBordersSize_REAL
|
||||
#define SDL_SetWindowOpacity SDL_SetWindowOpacity_REAL
|
||||
#define SDL_GetWindowOpacity SDL_GetWindowOpacity_REAL
|
||||
|
|
|
@ -633,3 +633,5 @@ SDL_DYNAPI_PROC(SDL_GameController*,SDL_GameControllerFromInstanceID,(SDL_Joysti
|
|||
SDL_DYNAPI_PROC(SDL_Joystick*,SDL_JoystickFromInstanceID,(SDL_JoystickID a),(a),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_GetDisplayUsableBounds,(int a, SDL_Rect *b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_GetWindowBordersSize,(SDL_Window *a, int *b, int *c, int *d, int *e),(a,b,c,d,e),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_SetWindowOpacity,(SDL_Window *a, float b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_GetWindowOpacity,(SDL_Window *a, float *b),(a,b),return)
|
||||
|
|
|
@ -1368,6 +1368,24 @@ SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case SDLK_o:
|
||||
if (withControl) {
|
||||
/* Ctrl-O (or Ctrl-Shift-O) changes window opacity. */
|
||||
SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
|
||||
if (window) {
|
||||
float opacity;
|
||||
if (SDL_GetWindowOpacity(window, &opacity) == 0) {
|
||||
if (withShift) {
|
||||
opacity += 0.20f;
|
||||
} else {
|
||||
opacity -= 0.20f;
|
||||
}
|
||||
SDL_SetWindowOpacity(window, opacity);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SDLK_c:
|
||||
if (withControl) {
|
||||
/* Ctrl-C copy awesome text! */
|
||||
|
|
|
@ -86,6 +86,8 @@ struct SDL_Window
|
|||
|
||||
SDL_DisplayMode fullscreen_mode;
|
||||
|
||||
float opacity;
|
||||
|
||||
float brightness;
|
||||
Uint16 *gamma;
|
||||
Uint16 *saved_gamma; /* (just offset into gamma) */
|
||||
|
@ -207,6 +209,7 @@ struct SDL_VideoDevice
|
|||
void (*SetWindowMinimumSize) (_THIS, SDL_Window * window);
|
||||
void (*SetWindowMaximumSize) (_THIS, SDL_Window * window);
|
||||
int (*GetWindowBordersSize) (_THIS, SDL_Window * window, int *top, int *left, int *bottom, int *right);
|
||||
int (*SetWindowOpacity) (_THIS, SDL_Window * window, float opacity);
|
||||
void (*ShowWindow) (_THIS, SDL_Window * window);
|
||||
void (*HideWindow) (_THIS, SDL_Window * window);
|
||||
void (*RaiseWindow) (_THIS, SDL_Window * window);
|
||||
|
|
|
@ -1415,6 +1415,7 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
|
|||
}
|
||||
window->flags = ((flags & CREATE_FLAGS) | SDL_WINDOW_HIDDEN);
|
||||
window->last_fullscreen_flags = window->flags;
|
||||
window->opacity = 1.0f;
|
||||
window->brightness = 1.0f;
|
||||
window->next = _this->windows;
|
||||
window->is_destroying = SDL_FALSE;
|
||||
|
@ -1475,6 +1476,7 @@ SDL_CreateWindowFrom(const void *data)
|
|||
window->flags = SDL_WINDOW_FOREIGN;
|
||||
window->last_fullscreen_flags = window->flags;
|
||||
window->is_destroying = SDL_FALSE;
|
||||
window->opacity = 1.0f;
|
||||
window->brightness = 1.0f;
|
||||
window->next = _this->windows;
|
||||
if (_this->windows) {
|
||||
|
@ -2190,6 +2192,42 @@ SDL_GetWindowBrightness(SDL_Window * window)
|
|||
return window->brightness;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SetWindowOpacity(SDL_Window * window, float opacity)
|
||||
{
|
||||
int retval;
|
||||
CHECK_WINDOW_MAGIC(window, -1);
|
||||
|
||||
if (!_this->SetWindowOpacity) {
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
if (opacity < 0.0f) {
|
||||
opacity = 0.0f;
|
||||
} else if (opacity > 1.0f) {
|
||||
opacity = 1.0f;
|
||||
}
|
||||
|
||||
retval = _this->SetWindowOpacity(_this, window, opacity);
|
||||
if (retval == 0) {
|
||||
window->opacity = opacity;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_GetWindowOpacity(SDL_Window * window, float * out_opacity)
|
||||
{
|
||||
CHECK_WINDOW_MAGIC(window, -1);
|
||||
|
||||
if (out_opacity) {
|
||||
*out_opacity = window->opacity;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SetWindowGammaRamp(SDL_Window * window, const Uint16 * red,
|
||||
const Uint16 * green,
|
||||
|
|
|
@ -87,6 +87,7 @@ Cocoa_CreateDevice(int devindex)
|
|||
device->SetWindowSize = Cocoa_SetWindowSize;
|
||||
device->SetWindowMinimumSize = Cocoa_SetWindowMinimumSize;
|
||||
device->SetWindowMaximumSize = Cocoa_SetWindowMaximumSize;
|
||||
device->SetWindowOpacity = Cocoa_SetWindowOpacity;
|
||||
device->ShowWindow = Cocoa_ShowWindow;
|
||||
device->HideWindow = Cocoa_HideWindow;
|
||||
device->RaiseWindow = Cocoa_RaiseWindow;
|
||||
|
|
|
@ -125,6 +125,7 @@ extern void Cocoa_SetWindowPosition(_THIS, SDL_Window * window);
|
|||
extern void Cocoa_SetWindowSize(_THIS, SDL_Window * window);
|
||||
extern void Cocoa_SetWindowMinimumSize(_THIS, SDL_Window * window);
|
||||
extern void Cocoa_SetWindowMaximumSize(_THIS, SDL_Window * window);
|
||||
extern int Cocoa_SetWindowOpacity(_THIS, SDL_Window * window, float opacity);
|
||||
extern void Cocoa_ShowWindow(_THIS, SDL_Window * window);
|
||||
extern void Cocoa_HideWindow(_THIS, SDL_Window * window);
|
||||
extern void Cocoa_RaiseWindow(_THIS, SDL_Window * window);
|
||||
|
|
|
@ -1782,6 +1782,14 @@ Cocoa_SetWindowHitTest(SDL_Window * window, SDL_bool enabled)
|
|||
return 0; /* just succeed, the real work is done elsewhere. */
|
||||
}
|
||||
|
||||
int
|
||||
Cocoa_SetWindowOpacity(_THIS, SDL_Window * window, float opacity)
|
||||
{
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
[data->nswindow setAlphaValue:opacity];
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_COCOA */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -121,6 +121,7 @@ DirectFB_CreateDevice(int devindex)
|
|||
device->SetWindowIcon = DirectFB_SetWindowIcon;
|
||||
device->SetWindowPosition = DirectFB_SetWindowPosition;
|
||||
device->SetWindowSize = DirectFB_SetWindowSize;
|
||||
device->SetWindowOpacity = DirectFB_SetWindowOpacity;
|
||||
device->ShowWindow = DirectFB_ShowWindow;
|
||||
device->HideWindow = DirectFB_HideWindow;
|
||||
device->RaiseWindow = DirectFB_RaiseWindow;
|
||||
|
|
|
@ -529,4 +529,17 @@ DirectFB_AdjustWindowSurface(SDL_Window * window)
|
|||
return;
|
||||
}
|
||||
|
||||
int
|
||||
DirectFB_SetWindowOpacity(_THIS, SDL_Window * window, float opacity)
|
||||
{
|
||||
const Uint8 alpha = (Uint8) ((unsigned int) (opacity * 255.0f));
|
||||
SDL_DFB_WINDOWDATA(window);
|
||||
SDL_DFB_CHECKERR(windata->dfbwin->SetOpacity(windata->dfbwin, alpha));
|
||||
windata->opacity = alpha;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
|
||||
|
|
|
@ -75,6 +75,7 @@ extern SDL_bool DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window,
|
|||
struct SDL_SysWMinfo *info);
|
||||
|
||||
extern void DirectFB_AdjustWindowSurface(SDL_Window * window);
|
||||
extern int DirectFB_SetWindowOpacity(_THIS, SDL_Window * window, float opacity);
|
||||
|
||||
#endif /* _SDL_directfb_window_h */
|
||||
|
||||
|
|
|
@ -137,6 +137,7 @@ WIN_CreateDevice(int devindex)
|
|||
device->SetWindowIcon = WIN_SetWindowIcon;
|
||||
device->SetWindowPosition = WIN_SetWindowPosition;
|
||||
device->SetWindowSize = WIN_SetWindowSize;
|
||||
device->SetWindowOpacity = WIN_SetWindowOpacity;
|
||||
device->ShowWindow = WIN_ShowWindow;
|
||||
device->HideWindow = WIN_HideWindow;
|
||||
device->RaiseWindow = WIN_RaiseWindow;
|
||||
|
|
|
@ -826,6 +826,39 @@ WIN_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
|
|||
return 0; /* just succeed, the real work is done elsewhere. */
|
||||
}
|
||||
|
||||
int
|
||||
WIN_SetWindowOpacity(_THIS, SDL_Window * window, float opacity)
|
||||
{
|
||||
const SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
const HWND hwnd = data->hwnd;
|
||||
const LONG style = GetWindowLong(hwnd, GWL_EXSTYLE);
|
||||
|
||||
SDL_assert(style != 0);
|
||||
|
||||
if (opacity == 1.0f) {
|
||||
/* want it fully opaque, just mark it unlayered if necessary. */
|
||||
if (style & WS_EX_LAYERED) {
|
||||
if (SetWindowLong(hwnd, GWL_EXSTYLE, style & ~WS_EX_LAYERED) == 0) {
|
||||
return WIN_SetError("SetWindowLong()");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const BYTE alpha = (BYTE) ((int) (opacity * 255.0f));
|
||||
/* want it transparent, mark it layered if necessary. */
|
||||
if ((style & WS_EX_LAYERED) == 0) {
|
||||
if (SetWindowLong(hwnd, GWL_EXSTYLE, style | WS_EX_LAYERED) == 0) {
|
||||
return WIN_SetError("SetWindowLong()");
|
||||
}
|
||||
}
|
||||
|
||||
if (SetLayeredWindowAttributes(hwnd, 0, alpha, LWA_ALPHA) == 0) {
|
||||
return WIN_SetError("SetLayeredWindowAttributes()");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -56,6 +56,7 @@ extern void WIN_SetWindowTitle(_THIS, SDL_Window * window);
|
|||
extern void WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon);
|
||||
extern void WIN_SetWindowPosition(_THIS, SDL_Window * window);
|
||||
extern void WIN_SetWindowSize(_THIS, SDL_Window * window);
|
||||
extern int WIN_SetWindowOpacity(_THIS, SDL_Window * window, float opacity);
|
||||
extern void WIN_ShowWindow(_THIS, SDL_Window * window);
|
||||
extern void WIN_HideWindow(_THIS, SDL_Window * window);
|
||||
extern void WIN_RaiseWindow(_THIS, SDL_Window * window);
|
||||
|
|
|
@ -233,6 +233,7 @@ X11_CreateDevice(int devindex)
|
|||
device->SetWindowMinimumSize = X11_SetWindowMinimumSize;
|
||||
device->SetWindowMaximumSize = X11_SetWindowMaximumSize;
|
||||
device->GetWindowBordersSize = X11_GetWindowBordersSize;
|
||||
device->SetWindowOpacity = X11_SetWindowOpacity;
|
||||
device->ShowWindow = X11_ShowWindow;
|
||||
device->HideWindow = X11_HideWindow;
|
||||
device->RaiseWindow = X11_RaiseWindow;
|
||||
|
@ -407,6 +408,7 @@ X11_VideoInit(_THIS)
|
|||
GET_ATOM(_NET_WM_ICON_NAME);
|
||||
GET_ATOM(_NET_WM_ICON);
|
||||
GET_ATOM(_NET_WM_PING);
|
||||
GET_ATOM(_NET_WM_WINDOW_OPACITY);
|
||||
GET_ATOM(_NET_WM_USER_TIME);
|
||||
GET_ATOM(_NET_ACTIVE_WINDOW);
|
||||
GET_ATOM(UTF8_STRING);
|
||||
|
|
|
@ -104,6 +104,7 @@ typedef struct SDL_VideoData
|
|||
Atom _NET_WM_ICON_NAME;
|
||||
Atom _NET_WM_ICON;
|
||||
Atom _NET_WM_PING;
|
||||
Atom _NET_WM_WINDOW_OPACITY;
|
||||
Atom _NET_WM_USER_TIME;
|
||||
Atom _NET_ACTIVE_WINDOW;
|
||||
Atom UTF8_STRING;
|
||||
|
|
|
@ -923,6 +923,25 @@ X11_GetWindowBordersSize(_THIS, SDL_Window * window, int *top, int *left, int *b
|
|||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
X11_SetWindowOpacity(_THIS, SDL_Window * window, float opacity)
|
||||
{
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
Display *display = data->videodata->display;
|
||||
Atom _NET_WM_WINDOW_OPACITY = data->videodata->_NET_WM_WINDOW_OPACITY;
|
||||
|
||||
if (opacity == 1.0f) {
|
||||
X11_XDeleteProperty(display, data->xwindow, _NET_WM_WINDOW_OPACITY);
|
||||
} else {
|
||||
const Uint32 FullyOpaque = 0xFFFFFFFF;
|
||||
const long alpha = (long) ((double)opacity * (double)FullyOpaque);
|
||||
X11_XChangeProperty(display, data->xwindow, _NET_WM_WINDOW_OPACITY, XA_CARDINAL, 32,
|
||||
PropModeReplace, (unsigned char *)&alpha, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
X11_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
|
||||
{
|
||||
|
|
|
@ -80,6 +80,7 @@ extern void X11_SetWindowPosition(_THIS, SDL_Window * window);
|
|||
extern void X11_SetWindowMinimumSize(_THIS, SDL_Window * window);
|
||||
extern void X11_SetWindowMaximumSize(_THIS, SDL_Window * window);
|
||||
extern int X11_GetWindowBordersSize(_THIS, SDL_Window * window, int *top, int *left, int *bottom, int *right);
|
||||
extern int X11_SetWindowOpacity(_THIS, SDL_Window * window, float opacity);
|
||||
extern void X11_SetWindowSize(_THIS, SDL_Window * window);
|
||||
extern void X11_ShowWindow(_THIS, SDL_Window * window);
|
||||
extern void X11_HideWindow(_THIS, SDL_Window * window);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue