For those interested in how this issue is solved I have this working. So I will post some code snippets.
The header file looks like this:
typedef double ramp_type;
#ifdef __WIN32__
#include <windows.h>
typedef unsigned short ramp_type_private;
typedef HDC displayHandle;
#elif defined (__APPLE__)
#ifndef DEBUG
#define DEBUG 0
#endif
#include <Carbon/Carbon.h>
#include <CoreServices/CoreServices.h>
#include <IOKit/Graphics/IOGraphicsLib.h>
typedef CGGammaValue ramp_type_private;
typedef CGDirectDisplayID displayHandle;
#elif defined (UNIX)
typedef unsigned short ramp_type_private;
typedef int displayHandle;
#else
#error "no typedef for ramp_type_private and displayHandle are available for your platform"
#endif
class gamma_ramp
{
public:
int size;
ramp_type *red, *green, *blue;
gamma_ramp(int screen, int leftIn, int topIn); // screen is ignored on OS/X and Windows
// leftIn and topIn are ignored on X11
~gamma_ramp();
void getGammaRamp(); // returns size
void setGammaRamp();
void setLinearGammaRamp();
private:
int getGammaRampSize();
void convertPrivShort2ramp_type();
void convert_ramp_type2short();
ramp_type_private* ramp_buffer;
int screen, left, top;
displayHandle display;
};
typedef double ramp_type;
#ifdef __WIN32__
#include <windows.h>
typedef unsigned short ramp_type_private;
typedef HDC displayHandle;
#elif defined (__APPLE__)
#ifndef DEBUG
#define DEBUG 0
#endif
#include <Carbon/Carbon.h>
#include <CoreServices/CoreServices.h>
#include <IOKit/Graphics/IOGraphicsLib.h>
typedef CGGammaValue ramp_type_private;
typedef CGDirectDisplayID displayHandle;
#elif defined (UNIX)
typedef unsigned short ramp_type_private;
typedef int displayHandle;
#else
#error "no typedef for ramp_type_private and displayHandle are available for your platform"
#endif
class gamma_ramp
{
public:
int size;
ramp_type *red, *green, *blue;
gamma_ramp(int screen, int leftIn, int topIn); // screen is ignored on OS/X and Windows
// leftIn and topIn are ignored on X11
~gamma_ramp();
void getGammaRamp(); // returns size
void setGammaRamp();
void setLinearGammaRamp();
private:
int getGammaRampSize();
void convertPrivShort2ramp_type();
void convert_ramp_type2short();
ramp_type_private* ramp_buffer;
int screen, left, top;
displayHandle display;
};
To copy to clipboard, switch view to plain text mode
The main thing of interest is how the code gets the handle to the display device so that it manipulates the correct video card gamma table.
For OS/X it looks like this:
CGPoint point;
CGDirectDisplayID getDisplay()
{
const int maxDisplays = 64; // 64 should be enough for any system
CGDisplayErr displayStatus;
CGDisplayCount displayCount; // Total number of display IDs
CGDirectDisplayID displayIDs[maxDisplays]; // Array of display IDs
displayStatus = CGGetDisplaysWithPoint ( point, maxDisplays, displayIDs, &displayCount);
if (displayStatus != kCGErrorSuccess || displayCount!= 1)
{
printf("CGGetDisplaysWithPoint returned error or the wrong number of displays\n");
return NULL;
}
else
return displayIDs[0];
}
gamma_ramp::gamma_ramp(int Screen, int leftIn, int topIn)
{
// screen = Screen;
left = leftIn;
top = topIn;
point.y = float(top);
point.x = float(left);
display = getDisplay();
screen = 0;
if (display == NULL)
{
ramp_buffer = 0;
red = 0;
green = 0;
blue = 0;
printf("gamma_ramp::gamma_ramp - error failed to get display handle");
}
else // do what needs to be done to set up the gamma tables
}
CGPoint point;
CGDirectDisplayID getDisplay()
{
const int maxDisplays = 64; // 64 should be enough for any system
CGDisplayErr displayStatus;
CGDisplayCount displayCount; // Total number of display IDs
CGDirectDisplayID displayIDs[maxDisplays]; // Array of display IDs
displayStatus = CGGetDisplaysWithPoint ( point, maxDisplays, displayIDs, &displayCount);
if (displayStatus != kCGErrorSuccess || displayCount!= 1)
{
printf("CGGetDisplaysWithPoint returned error or the wrong number of displays\n");
return NULL;
}
else
return displayIDs[0];
}
gamma_ramp::gamma_ramp(int Screen, int leftIn, int topIn)
{
// screen = Screen;
left = leftIn;
top = topIn;
point.y = float(top);
point.x = float(left);
display = getDisplay();
screen = 0;
if (display == NULL)
{
ramp_buffer = 0;
red = 0;
green = 0;
blue = 0;
printf("gamma_ramp::gamma_ramp - error failed to get display handle");
}
else // do what needs to be done to set up the gamma tables
}
To copy to clipboard, switch view to plain text mode
On Windows it looks like this:
static int numMatchingDisplays;
static RECT clipRegion;
static BOOL CALLBACK MonitorEnumProc(
HMONITOR hMonitor, // handle to display monitor
HDC hdcMonitor, // NULL, because EnumDisplayMonitors hdc is NULL
LPRECT displayCoordintes, // Virtual screen coordinates of this monitor
LPARAM name // Context data used to pass back display name in our case
)
{
MONITORINFOEX pmi;
if (displayCoordintes -> left <= clipRegion.left &&
displayCoordintes -> bottom >= clipRegion.top &&
displayCoordintes -> right >= clipRegion.left &&
displayCoordintes -> top <= clipRegion.top)
{
// display contains the widget
pmi.cbSize = sizeof(MONITORINFOEX);
if (GetMonitorInfo(hMonitor, (MONITORINFO *)&pmi) == 0)
{
printf("MonitorEnumProc - get_displays failed GetMonitorInfo\n");
return FALSE;
}
else // it worked we have the device we want
{
numMatchingDisplays++;
return TRUE;
}
}
else // this is OK as the device is not the one we want
{
return TRUE;
}
}
HDC getDisplay()
{
BOOL (WINAPI* pEnumDisplayDevices)(PVOID,DWORD,PVOID,DWORD);
char name[256];
HDC dispHand;
pEnumDisplayDevices = (BOOL (WINAPI*)(PVOID,DWORD,PVOID,DWORD)) GetProcAddress(LoadLibrary("USER32"), "EnumDisplayDevicesA");
numMatchingDisplays = 0;
if (EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM)&name) == 0)
{
printf("getDisplay - EnumDisplayMonitors failed\n");
return NULL;
}
if (numMatchingDisplays != 1 ) // there is a problem we should only have one
{
printf("getDisplay - wrong number of displays %i", numMatchingDisplays);
return NULL;
}
else
{
if ((dispHand = CreateDC(name, name, NULL, NULL)) == NULL)
{
printf("getDisplay - CreateDC failed");
return NULL;
}
else
{
return dispHand;
}
}
}
gamma_ramp::gamma_ramp(int Screen, int leftIn, int topIn)
{
screen = Screen;
left = leftIn;
top = topIn;
clipRegion.left = left;
clipRegion.top = top;
display = getDisplay();
if (display == NULL)
{
ramp_buffer = 0;
red = 0;
green = 0;
blue = 0;
printf("gamma_ramp::gamma_ramp - error failed to get display handle");
}
else // set up the gamma tables
}
static int numMatchingDisplays;
static RECT clipRegion;
static BOOL CALLBACK MonitorEnumProc(
HMONITOR hMonitor, // handle to display monitor
HDC hdcMonitor, // NULL, because EnumDisplayMonitors hdc is NULL
LPRECT displayCoordintes, // Virtual screen coordinates of this monitor
LPARAM name // Context data used to pass back display name in our case
)
{
MONITORINFOEX pmi;
if (displayCoordintes -> left <= clipRegion.left &&
displayCoordintes -> bottom >= clipRegion.top &&
displayCoordintes -> right >= clipRegion.left &&
displayCoordintes -> top <= clipRegion.top)
{
// display contains the widget
pmi.cbSize = sizeof(MONITORINFOEX);
if (GetMonitorInfo(hMonitor, (MONITORINFO *)&pmi) == 0)
{
printf("MonitorEnumProc - get_displays failed GetMonitorInfo\n");
return FALSE;
}
else // it worked we have the device we want
{
numMatchingDisplays++;
return TRUE;
}
}
else // this is OK as the device is not the one we want
{
return TRUE;
}
}
HDC getDisplay()
{
BOOL (WINAPI* pEnumDisplayDevices)(PVOID,DWORD,PVOID,DWORD);
char name[256];
HDC dispHand;
pEnumDisplayDevices = (BOOL (WINAPI*)(PVOID,DWORD,PVOID,DWORD)) GetProcAddress(LoadLibrary("USER32"), "EnumDisplayDevicesA");
numMatchingDisplays = 0;
if (EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM)&name) == 0)
{
printf("getDisplay - EnumDisplayMonitors failed\n");
return NULL;
}
if (numMatchingDisplays != 1 ) // there is a problem we should only have one
{
printf("getDisplay - wrong number of displays %i", numMatchingDisplays);
return NULL;
}
else
{
if ((dispHand = CreateDC(name, name, NULL, NULL)) == NULL)
{
printf("getDisplay - CreateDC failed");
return NULL;
}
else
{
return dispHand;
}
}
}
gamma_ramp::gamma_ramp(int Screen, int leftIn, int topIn)
{
screen = Screen;
left = leftIn;
top = topIn;
clipRegion.left = left;
clipRegion.top = top;
display = getDisplay();
if (display == NULL)
{
ramp_buffer = 0;
red = 0;
green = 0;
blue = 0;
printf("gamma_ramp::gamma_ramp - error failed to get display handle");
}
else // set up the gamma tables
}
To copy to clipboard, switch view to plain text mode
On X11 I just pass in the desktop -> screenNumber since X11 uses this to allow access to the video card gamma table. For for OS/X and Windows I needed to pass in a set of coordinates that were located on the display I wanted to manipulate the gamma table for and then parse through a list of devices to find the one that contained these coordinates and then get it's handle to use internal in the gamma_ramp class.
Bookmarks