Add SDL_GetWindowICCProfile(). (#4314)
* Add SDL_GetWindowICCProfile * Add new SDL display events * Implement ICC profile change event for macOS * Implement ICC profile notification for Windows * Fix SDL_GetWindowICCProfile() for X11 * Fix compile errorsmain
parent
a34fe8161f
commit
19dee1cd16
|
@ -174,7 +174,9 @@ typedef enum
|
|||
SDL_WINDOWEVENT_FOCUS_LOST, /**< Window has lost keyboard focus */
|
||||
SDL_WINDOWEVENT_CLOSE, /**< The window manager requests that the window be closed */
|
||||
SDL_WINDOWEVENT_TAKE_FOCUS, /**< Window is being offered a focus (should SetWindowInputFocus() on itself or a subwindow, or ignore) */
|
||||
SDL_WINDOWEVENT_HIT_TEST /**< Window had a hit test that wasn't SDL_HITTEST_NORMAL. */
|
||||
SDL_WINDOWEVENT_HIT_TEST, /**< Window had a hit test that wasn't SDL_HITTEST_NORMAL. */
|
||||
SDL_WINDOWEVENT_ICCPROF_CHANGED,/**< The ICC profile of the window's display has changed. */
|
||||
SDL_WINDOWEVENT_DISPLAY_CHANGED /**< Window has been moved to display data1. */
|
||||
} SDL_WindowEventID;
|
||||
|
||||
/**
|
||||
|
@ -613,6 +615,17 @@ extern DECLSPEC int SDLCALL SDL_SetWindowDisplayMode(SDL_Window * window,
|
|||
extern DECLSPEC int SDLCALL SDL_GetWindowDisplayMode(SDL_Window * window,
|
||||
SDL_DisplayMode * mode);
|
||||
|
||||
/**
|
||||
* Get the raw ICC profile data for the screen the window is currently on.
|
||||
* Data returned should be freed with SDL_free.
|
||||
*
|
||||
* \param window the window to query
|
||||
* \param size the size of the ICC profile
|
||||
* \returns the raw ICC profile data on success or NULL on failure;
|
||||
* call SDL_GetError() for more information.
|
||||
*/
|
||||
extern DECLSPEC void* SDLCALL SDL_GetWindowICCProfile(SDL_Window * window, size_t* size);
|
||||
|
||||
/**
|
||||
* Get the pixel format associated with the window.
|
||||
*
|
||||
|
|
|
@ -822,3 +822,4 @@
|
|||
#define SDL_RenderSetVSync SDL_RenderSetVSync_REAL
|
||||
#define SDL_asprintf SDL_asprintf_REAL
|
||||
#define SDL_vasprintf SDL_vasprintf_REAL
|
||||
#define SDL_GetWindowICCProfile SDL_GetWindowICCProfile_REAL
|
||||
|
|
|
@ -889,3 +889,4 @@ SDL_DYNAPI_PROC(int,SDL_RenderSetVSync,(SDL_Renderer *a, int b),(a,b),return)
|
|||
SDL_DYNAPI_PROC(int,SDL_asprintf,(char **a, SDL_PRINTF_FORMAT_STRING const char *b, ...),(a,b),return)
|
||||
#endif
|
||||
SDL_DYNAPI_PROC(int,SDL_vasprintf,(char **a, const char *b, va_list c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(void*,SDL_GetWindowICCProfile,(SDL_Window *a, size_t *b),(a,b),return)
|
||||
|
|
|
@ -110,6 +110,7 @@ SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, int data1,
|
|||
}
|
||||
window->x = data1;
|
||||
window->y = data2;
|
||||
SDL_OnWindowMoved(window);
|
||||
break;
|
||||
case SDL_WINDOWEVENT_RESIZED:
|
||||
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
|
||||
|
|
|
@ -83,6 +83,7 @@ struct SDL_Window
|
|||
int max_w, max_h;
|
||||
Uint32 flags;
|
||||
Uint32 last_fullscreen_flags;
|
||||
Uint32 display_index;
|
||||
|
||||
/* Stored position and size for windowed mode */
|
||||
SDL_Rect windowed;
|
||||
|
@ -233,6 +234,7 @@ struct SDL_VideoDevice
|
|||
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);
|
||||
void* (*GetWindowICCProfile) (_THIS, SDL_Window * window, size_t* size);
|
||||
void (*SetWindowMouseGrab) (_THIS, SDL_Window * window, SDL_bool grabbed);
|
||||
void (*SetWindowKeyboardGrab) (_THIS, SDL_Window * window, SDL_bool grabbed);
|
||||
void (*DestroyWindow) (_THIS, SDL_Window * window);
|
||||
|
@ -466,6 +468,7 @@ extern SDL_bool SDL_HasWindows(void);
|
|||
|
||||
extern void SDL_OnWindowShown(SDL_Window * window);
|
||||
extern void SDL_OnWindowHidden(SDL_Window * window);
|
||||
extern void SDL_OnWindowMoved(SDL_Window * window);
|
||||
extern void SDL_OnWindowResized(SDL_Window * window);
|
||||
extern void SDL_OnWindowMinimized(SDL_Window * window);
|
||||
extern void SDL_OnWindowRestored(SDL_Window * window);
|
||||
|
|
|
@ -1207,6 +1207,16 @@ SDL_GetWindowDisplayMode(SDL_Window * window, SDL_DisplayMode * mode)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void*
|
||||
SDL_GetWindowICCProfile(SDL_Window * window, size_t* size)
|
||||
{
|
||||
if (!_this->GetWindowICCProfile) {
|
||||
SDL_Unsupported();
|
||||
return NULL;
|
||||
}
|
||||
return _this->GetWindowICCProfile(_this, window, size);
|
||||
}
|
||||
|
||||
Uint32
|
||||
SDL_GetWindowPixelFormat(SDL_Window * window)
|
||||
{
|
||||
|
@ -1628,6 +1638,7 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
|
|||
window->brightness = 1.0f;
|
||||
window->next = _this->windows;
|
||||
window->is_destroying = SDL_FALSE;
|
||||
window->display_index = SDL_GetWindowDisplayIndex(window);
|
||||
|
||||
if (_this->windows) {
|
||||
_this->windows->prev = window;
|
||||
|
@ -1707,6 +1718,7 @@ SDL_CreateWindowFrom(const void *data)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
window->display_index = SDL_GetWindowDisplayIndex(window);
|
||||
PrepareDragAndDropSupport(window);
|
||||
|
||||
return window;
|
||||
|
@ -2844,10 +2856,27 @@ SDL_OnWindowHidden(SDL_Window * window)
|
|||
void
|
||||
SDL_OnWindowResized(SDL_Window * window)
|
||||
{
|
||||
int display_index = SDL_GetWindowDisplayIndex(window);
|
||||
window->surface_valid = SDL_FALSE;
|
||||
|
||||
if (!window->is_destroying) {
|
||||
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h);
|
||||
|
||||
if (display_index != window->display_index && display_index != -1) {
|
||||
window->display_index = display_index;
|
||||
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_DISPLAY_CHANGED, window->display_index, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SDL_OnWindowMoved(SDL_Window * window)
|
||||
{
|
||||
int display_index = SDL_GetWindowDisplayIndex(window);
|
||||
|
||||
if (!window->is_destroying && display_index != window->display_index && display_index != -1) {
|
||||
window->display_index = display_index;
|
||||
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_DISPLAY_CHANGED, window->display_index, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -102,6 +102,7 @@ Cocoa_CreateDevice(int devindex)
|
|||
device->SetWindowFullscreen = Cocoa_SetWindowFullscreen;
|
||||
device->SetWindowGammaRamp = Cocoa_SetWindowGammaRamp;
|
||||
device->GetWindowGammaRamp = Cocoa_GetWindowGammaRamp;
|
||||
device->GetWindowICCProfile = Cocoa_GetWindowICCProfile;
|
||||
device->SetWindowMouseGrab = Cocoa_SetWindowMouseGrab;
|
||||
device->SetWindowKeyboardGrab = Cocoa_SetWindowKeyboardGrab;
|
||||
device->DestroyWindow = Cocoa_DestroyWindow;
|
||||
|
|
|
@ -80,6 +80,7 @@ typedef enum
|
|||
-(void) windowDidBecomeKey:(NSNotification *) aNotification;
|
||||
-(void) windowDidResignKey:(NSNotification *) aNotification;
|
||||
-(void) windowDidChangeBackingProperties:(NSNotification *) aNotification;
|
||||
-(void) windowDidChangeScreenProfile:(NSNotification *) aNotification;
|
||||
-(void) windowWillEnterFullScreen:(NSNotification *) aNotification;
|
||||
-(void) windowDidEnterFullScreen:(NSNotification *) aNotification;
|
||||
-(void) windowWillExitFullScreen:(NSNotification *) aNotification;
|
||||
|
@ -151,6 +152,7 @@ extern void Cocoa_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resiza
|
|||
extern void Cocoa_SetWindowAlwaysOnTop(_THIS, SDL_Window * window, SDL_bool on_top);
|
||||
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 void* Cocoa_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size);
|
||||
extern int Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp);
|
||||
extern void Cocoa_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
|
||||
extern void Cocoa_DestroyWindow(_THIS, SDL_Window * window);
|
||||
|
|
|
@ -352,6 +352,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
|
|||
[center addObserver:self selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification object:window];
|
||||
[center addObserver:self selector:@selector(windowDidResignKey:) name:NSWindowDidResignKeyNotification object:window];
|
||||
[center addObserver:self selector:@selector(windowDidChangeBackingProperties:) name:NSWindowDidChangeBackingPropertiesNotification object:window];
|
||||
[center addObserver:self selector:@selector(windowDidChangeScreenProfile:) name:NSWindowDidChangeScreenProfileNotification object:window];
|
||||
[center addObserver:self selector:@selector(windowWillEnterFullScreen:) name:NSWindowWillEnterFullScreenNotification object:window];
|
||||
[center addObserver:self selector:@selector(windowDidEnterFullScreen:) name:NSWindowDidEnterFullScreenNotification object:window];
|
||||
[center addObserver:self selector:@selector(windowWillExitFullScreen:) name:NSWindowWillExitFullScreenNotification object:window];
|
||||
|
@ -483,6 +484,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
|
|||
[center removeObserver:self name:NSWindowDidBecomeKeyNotification object:window];
|
||||
[center removeObserver:self name:NSWindowDidResignKeyNotification object:window];
|
||||
[center removeObserver:self name:NSWindowDidChangeBackingPropertiesNotification object:window];
|
||||
[center removeObserver:self name:NSWindowDidChangeScreenProfileNotification object:window];
|
||||
[center removeObserver:self name:NSWindowWillEnterFullScreenNotification object:window];
|
||||
[center removeObserver:self name:NSWindowDidEnterFullScreenNotification object:window];
|
||||
[center removeObserver:self name:NSWindowWillExitFullScreenNotification object:window];
|
||||
|
@ -750,6 +752,11 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
|
|||
}
|
||||
}
|
||||
|
||||
- (void)windowDidChangeScreenProfile:(NSNotification *)aNotification
|
||||
{
|
||||
SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_ICCPROF_CHANGED, 0, 0);
|
||||
}
|
||||
|
||||
- (void)windowWillEnterFullScreen:(NSNotification *)aNotification
|
||||
{
|
||||
SDL_Window *window = _data->window;
|
||||
|
@ -1981,6 +1988,42 @@ Cocoa_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void*
|
||||
Cocoa_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size)
|
||||
{
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
NSWindow *nswindow = data->nswindow;
|
||||
NSScreen *screen = [nswindow screen];
|
||||
NSData* iccProfileData = nil;
|
||||
void* retIccProfileData = NULL;
|
||||
|
||||
if (screen == nil) {
|
||||
SDL_SetError("Could not get screen of window.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ([screen colorSpace] == nil) {
|
||||
SDL_SetError("Could not get colorspace information of screen.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
iccProfileData = [[screen colorSpace] ICCProfileData];
|
||||
if (iccProfileData == nil) {
|
||||
SDL_SetError("Could not get ICC profile data.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
retIccProfileData = SDL_malloc([iccProfileData length]);
|
||||
if (!retIccProfileData) {
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
[iccProfileData getBytes:retIccProfileData length:[iccProfileData length]];
|
||||
*size = [iccProfileData length];
|
||||
return retIccProfileData;
|
||||
}
|
||||
|
||||
int
|
||||
Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp)
|
||||
{
|
||||
|
|
|
@ -590,6 +590,30 @@ WIN_KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void WIN_CheckICMProfileChanged(SDL_Window* window)
|
||||
{
|
||||
SDL_VideoDisplay* display = SDL_GetDisplayForWindow(window);
|
||||
SDL_DisplayData* data = (SDL_DisplayData*)display->driverdata;
|
||||
static WCHAR currentIcmFileName[MAX_PATH] = { '\0' };
|
||||
WCHAR icmFileName[MAX_PATH];
|
||||
HDC hdc;
|
||||
SDL_bool succeeded;
|
||||
DWORD fileNameSize = MAX_PATH;
|
||||
|
||||
hdc = CreateDCW(data->DeviceName, NULL, NULL, NULL);
|
||||
if (hdc) {
|
||||
succeeded = GetICMProfileW(hdc, &fileNameSize, icmFileName);
|
||||
DeleteDC(hdc);
|
||||
if (succeeded) {
|
||||
|
||||
if (SDL_wcsncmp(currentIcmFileName, icmFileName, fileNameSize)) {
|
||||
SDL_wcslcpy(currentIcmFileName, icmFileName, fileNameSize);
|
||||
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_ICCPROF_CHANGED, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CALLBACK
|
||||
WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
|
@ -655,6 +679,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
actually being the foreground window, but this appears to get called in all cases where
|
||||
the global foreground window changes to and from this window. */
|
||||
WIN_UpdateFocus(data->window);
|
||||
WIN_CheckICMProfileChanged(data->window);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1108,6 +1133,8 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
/* Forces a WM_PAINT event */
|
||||
InvalidateRect(hwnd, NULL, FALSE);
|
||||
|
||||
WIN_CheckICMProfileChanged(data->window);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -165,6 +165,7 @@ WIN_CreateDevice(int devindex)
|
|||
device->SetWindowAlwaysOnTop = WIN_SetWindowAlwaysOnTop;
|
||||
device->SetWindowFullscreen = WIN_SetWindowFullscreen;
|
||||
device->SetWindowGammaRamp = WIN_SetWindowGammaRamp;
|
||||
device->GetWindowICCProfile = WIN_GetWindowICCProfile;
|
||||
device->GetWindowGammaRamp = WIN_GetWindowGammaRamp;
|
||||
device->SetWindowMouseGrab = WIN_SetWindowMouseGrab;
|
||||
device->SetWindowKeyboardGrab = WIN_SetWindowKeyboardGrab;
|
||||
|
|
|
@ -725,6 +725,32 @@ WIN_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp)
|
|||
return succeeded ? 0 : -1;
|
||||
}
|
||||
|
||||
void*
|
||||
WIN_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size)
|
||||
{
|
||||
SDL_VideoDisplay* display = SDL_GetDisplayForWindow(window);
|
||||
SDL_DisplayData* data = (SDL_DisplayData*)display->driverdata;
|
||||
HDC hdc;
|
||||
BOOL succeeded = FALSE;
|
||||
WCHAR filename[MAX_PATH];
|
||||
DWORD fileNameSize = MAX_PATH;
|
||||
void* iccProfileData = NULL;
|
||||
|
||||
hdc = CreateDCW(data->DeviceName, NULL, NULL, NULL);
|
||||
if (hdc) {
|
||||
succeeded = GetICMProfileW(hdc, &fileNameSize, filename);
|
||||
DeleteDC(hdc);
|
||||
}
|
||||
|
||||
if (succeeded) {
|
||||
iccProfileData = SDL_LoadFile(WIN_StringToUTF8(filename), size);
|
||||
if (!iccProfileData)
|
||||
SDL_SetError("Could not open ICC profile");
|
||||
}
|
||||
|
||||
return iccProfileData;
|
||||
}
|
||||
|
||||
int
|
||||
WIN_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp)
|
||||
{
|
||||
|
|
|
@ -79,6 +79,7 @@ extern void WIN_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizabl
|
|||
extern void WIN_SetWindowAlwaysOnTop(_THIS, SDL_Window * window, SDL_bool on_top);
|
||||
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 void* WIN_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size);
|
||||
extern int WIN_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp);
|
||||
extern void WIN_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
|
||||
extern void WIN_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
|
||||
|
|
|
@ -820,6 +820,31 @@ X11_DispatchEvent(_THIS, XEvent *xevent)
|
|||
|
||||
X11_UpdateKeymap(_this);
|
||||
SDL_SendKeymapChangedEvent();
|
||||
} else if (xevent->type == PropertyNotify && videodata && videodata->windowlist) {
|
||||
char* name_of_atom = X11_XGetAtomName(display, xevent->xproperty.atom);
|
||||
|
||||
if (SDL_strncmp(name_of_atom, "_ICC_PROFILE", sizeof("_ICC_PROFILE") - 1) == 0) {
|
||||
XWindowAttributes attrib;
|
||||
int screennum;
|
||||
for (i = 0; i < videodata->numwindows; ++i) {
|
||||
if (videodata->windowlist[i] != NULL) {
|
||||
data = videodata->windowlist[i];
|
||||
X11_XGetWindowAttributes(display, data->xwindow, &attrib);
|
||||
screennum = X11_XScreenNumberOfScreen(attrib.screen);
|
||||
if (screennum == 0 && SDL_strcmp(name_of_atom, "_ICC_PROFILE") == 0) {
|
||||
SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_ICCPROF_CHANGED, 0, 0);
|
||||
} else if (SDL_strncmp(name_of_atom, "_ICC_PROFILE_", sizeof("_ICC_PROFILE_") - 1) == 0 && SDL_strlen(name_of_atom) > sizeof("_ICC_PROFILE_") - 1) {
|
||||
int iccscreennum = SDL_atoi(&name_of_atom[sizeof("_ICC_PROFILE_") - 1]);
|
||||
|
||||
if (screennum == iccscreennum) {
|
||||
SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_ICCPROF_CHANGED, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (name_of_atom) X11_XFree(name_of_atom);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -109,6 +109,7 @@ SDL_X11_SYM(int,XRaiseWindow,(Display* a,Window b),(a,b),return)
|
|||
SDL_X11_SYM(int,XReparentWindow,(Display* a,Window b,Window c,int d,int e),(a,b,c,d,e),return)
|
||||
SDL_X11_SYM(int,XResetScreenSaver,(Display* a),(a),return)
|
||||
SDL_X11_SYM(int,XResizeWindow,(Display* a,Window b,unsigned int c,unsigned int d),(a,b,c,d),return)
|
||||
SDL_X11_SYM(int,XScreenNumberOfScreen,(Screen* a),(a),return)
|
||||
SDL_X11_SYM(int,XSelectInput,(Display* a,Window b,long c),(a,b,c),return)
|
||||
SDL_X11_SYM(Status,XSendEvent,(Display* a,Window b,Bool c,long d,XEvent* e),(a,b,c,d,e),return)
|
||||
SDL_X11_SYM(XErrorHandler,XSetErrorHandler,(XErrorHandler a),(a),return)
|
||||
|
|
|
@ -215,6 +215,7 @@ X11_CreateDevice(int devindex)
|
|||
device->GetDisplayBounds = X11_GetDisplayBounds;
|
||||
device->GetDisplayUsableBounds = X11_GetDisplayUsableBounds;
|
||||
device->GetDisplayDPI = X11_GetDisplayDPI;
|
||||
device->GetWindowICCProfile = X11_GetWindowICCProfile;
|
||||
device->SetDisplayMode = X11_SetDisplayMode;
|
||||
device->SuspendScreenSaver = X11_SuspendScreenSaver;
|
||||
device->PumpEvents = X11_PumpEvents;
|
||||
|
|
|
@ -670,6 +670,9 @@ X11_CreateWindow(_THIS, SDL_Window * window)
|
|||
PropertyChangeMask | StructureNotifyMask |
|
||||
KeymapStateMask | fevent));
|
||||
|
||||
/* For _ICC_PROFILE. */
|
||||
X11_XSelectInput(display, RootWindow(display, screen), PropertyChangeMask);
|
||||
|
||||
X11_XkbSelectEvents(display, XkbUseCoreKbd, XkbStateNotifyMask, XkbStateNotifyMask);
|
||||
|
||||
X11_XFlush(display);
|
||||
|
@ -1581,6 +1584,86 @@ X11_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
unsigned char *data;
|
||||
int format, count;
|
||||
Atom type;
|
||||
} SDL_x11Prop;
|
||||
|
||||
/* Reads property
|
||||
Must call X11_XFree on results
|
||||
*/
|
||||
static void X11_ReadProperty(SDL_x11Prop *p, Display *disp, Window w, Atom prop)
|
||||
{
|
||||
unsigned char *ret=NULL;
|
||||
Atom type;
|
||||
int fmt;
|
||||
unsigned long count;
|
||||
unsigned long bytes_left;
|
||||
int bytes_fetch = 0;
|
||||
|
||||
do {
|
||||
if (ret != 0) X11_XFree(ret);
|
||||
X11_XGetWindowProperty(disp, w, prop, 0, bytes_fetch, False, AnyPropertyType, &type, &fmt, &count, &bytes_left, &ret);
|
||||
bytes_fetch += bytes_left;
|
||||
} while (bytes_left != 0);
|
||||
|
||||
p->data=ret;
|
||||
p->format=fmt;
|
||||
p->count=count;
|
||||
p->type=type;
|
||||
}
|
||||
|
||||
void*
|
||||
X11_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size)
|
||||
{
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
Display *display = data->videodata->display;
|
||||
XWindowAttributes attributes;
|
||||
Atom icc_profile_atom;
|
||||
char icc_atom_string[sizeof("_ICC_PROFILE_") + 12];
|
||||
void* ret_icc_profile_data = NULL;
|
||||
CARD8* icc_profile_data;
|
||||
int real_format;
|
||||
unsigned long real_nitems;
|
||||
SDL_x11Prop atomProp;
|
||||
|
||||
X11_XGetWindowAttributes(display, X11_IsWindowLegacyFullscreen(_this, window) ? data->fswindow : data->xwindow, &attributes);
|
||||
if (X11_XScreenNumberOfScreen(attributes.screen) > 0) {
|
||||
SDL_snprintf(icc_atom_string, sizeof("_ICC_PROFILE_") + 12, "%s%d", "_ICC_PROFILE_", X11_XScreenNumberOfScreen(attributes.screen));
|
||||
} else {
|
||||
SDL_strlcpy(icc_atom_string, "_ICC_PROFILE", sizeof("_ICC_PROFILE"));
|
||||
}
|
||||
X11_XGetWindowAttributes(display, RootWindowOfScreen(attributes.screen), &attributes);
|
||||
|
||||
icc_profile_atom = X11_XInternAtom(display, icc_atom_string, True);
|
||||
if (icc_profile_atom == None) {
|
||||
SDL_SetError("Screen is not calibrated.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
X11_ReadProperty(&atomProp, display, RootWindowOfScreen(attributes.screen), icc_profile_atom);
|
||||
real_format = atomProp.format;
|
||||
real_nitems = atomProp.count;
|
||||
icc_profile_data = atomProp.data;
|
||||
if (real_format == None) {
|
||||
SDL_SetError("Screen is not calibrated.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret_icc_profile_data = SDL_malloc(real_nitems);
|
||||
if (!ret_icc_profile_data) {
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SDL_memcpy(ret_icc_profile_data, icc_profile_data, real_nitems);
|
||||
*size = real_nitems;
|
||||
X11_XFree(icc_profile_data);
|
||||
|
||||
return ret_icc_profile_data;
|
||||
}
|
||||
|
||||
void
|
||||
X11_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
|
||||
{
|
||||
|
|
|
@ -102,6 +102,7 @@ extern void X11_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizabl
|
|||
extern void X11_SetWindowAlwaysOnTop(_THIS, SDL_Window * window, SDL_bool on_top);
|
||||
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_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size);
|
||||
extern void X11_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
|
||||
extern void X11_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
|
||||
extern void X11_DestroyWindow(_THIS, SDL_Window * window);
|
||||
|
|
Loading…
Reference in New Issue