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.
parent
5696e88e6b
commit
3bdaf4c611
|
@ -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…
Reference in New Issue