void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) { // TODO: Support ramp sizes other than 256 uint32_t sampleCount; int i; CGGammaValue red[GLFW_GAMMA_RAMP_SIZE]; CGGammaValue green[GLFW_GAMMA_RAMP_SIZE]; CGGammaValue blue[GLFW_GAMMA_RAMP_SIZE]; if (CGDisplayGammaTableCapacity(monitor->ns.displayID) != GLFW_GAMMA_RAMP_SIZE) { _glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Only gamma ramps of size 256 supported"); return; } CGGetDisplayTransferByTable(monitor->ns.displayID, GLFW_GAMMA_RAMP_SIZE, red, green, blue, &sampleCount); for (i = 0; i < GLFW_GAMMA_RAMP_SIZE; i++) { ramp->red[i] = red[i] * 65535; ramp->green[i] = green[i] * 65535; ramp->blue[i] = blue[i] * 65535; } }
int VID_GetGamma(unsigned short *ramps, int rampsize) { CGGammaValue table_red [GAMMA_TABLE_SIZE]; CGGammaValue table_green [GAMMA_TABLE_SIZE]; CGGammaValue table_blue [GAMMA_TABLE_SIZE]; CGTableCount actualsize = 0; int i; // Get the gamma ramps from the system if (CGGetDisplayTransferByTable(CGMainDisplayID(), rampsize, table_red, table_green, table_blue, &actualsize) != CGDisplayNoErr) { Con_Print("VID_GetGamma: ERROR: CGGetDisplayTransferByTable failed!\n"); return false; } if (actualsize != (unsigned int)rampsize) { Con_Printf("VID_GetGamma: ERROR: invalid gamma table size (%u != %u)\n", actualsize, rampsize); return false; } // Convert the 3 float tables into 1 unsigned short table for (i = 0; i < rampsize; i++) ramps[i] = table_red[i] * 65535.0f; for (i = 0; i < rampsize; i++) ramps[i + rampsize] = table_green[i] * 65535.0f; for (i = 0; i < rampsize; i++) ramps[i + 2 * rampsize] = table_blue[i] * 65535.0f; return true; }
int main(int argc, char *argv[]) { CGTableCount sampleCount; CGDisplayErr cgErr; Initialize(); MakeWindow(); MakeMenu(); // Grab original gamma settings cgErr = CGGetDisplayTransferByTable( 0, 256, gOriginalRedTable, gOriginalGreenTable, gOriginalBlueTable, &sampleCount); InstallTimer(); EventLoop(); // Restore original gamma settings cgErr = CGSetDisplayTransferByTable( 0, 256, gOriginalRedTable, gOriginalGreenTable, gOriginalBlueTable); return 0; }
int GGI_quartz_getgammamap(struct ggi_visual *vis, int start, int len, ggi_color *colormap) { ggi_quartz_priv *priv = QUARTZ_PRIV(vis); /* Note: If the compiler breaks here, * then it is not ANSI C99 conform. */ const CGTableCount tableSize = vis->gamma->len; CGGammaValue redTable[tableSize]; CGGammaValue greenTable[tableSize]; CGGammaValue blueTable[tableSize]; CGTableCount actualSize; int i; if (colormap==NULL) return GGI_EARGINVAL; if (start < 0 || start >= vis->gamma->len) return GGI_ENOSPACE; if (len > (vis->gamma->len - start)) return GGI_ENOSPACE; if ( CGDisplayNoErr != CGGetDisplayTransferByTable (priv->display_id, tableSize, redTable, greenTable, blueTable, &actualSize)) { return -1; } /* if */ if ((unsigned)len < actualSize) len = actualSize; if (len < start) return GGI_ENOSPACE; /* Pack tables into one array, with values from 0 to 65535 */ i = 0; do { colormap[i].r = redTable[start + i] * 65535.0; colormap[i].g = greenTable[start + i] * 65535.0; colormap[i].b = blueTable[start + i] * 65535.0; } while (i++ < len); return 0; } /* GGI_quartz_getgammamap */
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) { uint32_t i, size = CGDisplayGammaTableCapacity(monitor->ns.displayID); CGGammaValue* values = (CGGammaValue*) malloc(size * 3 * sizeof(CGGammaValue)); CGGetDisplayTransferByTable(monitor->ns.displayID, size, values, values + size, values + size * 2, &size); _glfwAllocGammaRamp(ramp, size); for (i = 0; i < size; i++) { ramp->red[i] = (unsigned short) (values[i] * 65535); ramp->green[i] = (unsigned short) (values[i + size] * 65535); ramp->blue[i] = (unsigned short) (values[i + size * 2] * 65535); } free(values); }
int quartz_start(quartz_state_t *state) { int r; CGError error; uint32_t display_count; /* Get display count */ error = CGGetOnlineDisplayList(0, NULL, &display_count); if (error != kCGErrorSuccess) return -1; state->display_count = display_count; CGDirectDisplayID* displays = malloc(sizeof(CGDirectDisplayID)*display_count); if (displays == NULL) { perror("malloc"); return -1; } /* Get list of displays */ error = CGGetOnlineDisplayList(display_count, displays, &display_count); if (error != kCGErrorSuccess) { free(displays); return -1; } /* Allocate list of display state */ state->displays = malloc(display_count * sizeof(quartz_display_state_t)); if (state->displays == NULL) { perror("malloc"); free(displays); return -1; } /* Copy display indentifiers to display state */ for (int i = 0; i < display_count; i++) { state->displays[i].display = displays[i]; state->displays[i].saved_ramps = NULL; } free(displays); /* Save gamma ramps for all displays in display state */ for (int i = 0; i < display_count; i++) { CGDirectDisplayID display = state->displays[i].display; uint32_t ramp_size = CGDisplayGammaTableCapacity(display); if (ramp_size == 0) { fprintf(stderr, _("Gamma ramp size too small: %i\n"), ramp_size); return -1; } state->displays[i].ramp_size = ramp_size; /* Allocate space for saved ramps */ state->displays[i].saved_ramps = malloc(3 * ramp_size * sizeof(float)); if (state->displays[i].saved_ramps == NULL) { perror("malloc"); return -1; } float *gamma_r = &state->displays[i].saved_ramps[0*ramp_size]; float *gamma_g = &state->displays[i].saved_ramps[1*ramp_size]; float *gamma_b = &state->displays[i].saved_ramps[2*ramp_size]; /* Copy the ramps to allocated space */ uint32_t sample_count; error = CGGetDisplayTransferByTable(display, ramp_size, gamma_r, gamma_g, gamma_b, &sample_count); if (error != kCGErrorSuccess || sample_count != ramp_size) { fputs(_("Unable to save current gamma ramp.\n"), stderr); return -1; } } return 0; }
/*********************************************************************** * GetDeviceGammaRamp (MACDRV.@) */ BOOL macdrv_GetDeviceGammaRamp(PHYSDEV dev, LPVOID ramp) { BOOL ret = FALSE; DDGAMMARAMP *r = ramp; struct macdrv_display *displays; int num_displays; uint32_t mac_entries; int win_entries = sizeof(r->red) / sizeof(r->red[0]); CGGammaValue *red, *green, *blue; CGError err; int win_entry; TRACE("dev %p ramp %p\n", dev, ramp); if (macdrv_get_displays(&displays, &num_displays)) { WARN("failed to get Mac displays\n"); return FALSE; } mac_entries = CGDisplayGammaTableCapacity(displays[0].displayID); red = HeapAlloc(GetProcessHeap(), 0, mac_entries * sizeof(red[0]) * 3); if (!red) goto done; green = red + mac_entries; blue = green + mac_entries; err = CGGetDisplayTransferByTable(displays[0].displayID, mac_entries, red, green, blue, &mac_entries); if (err != kCGErrorSuccess) { WARN("failed to get Mac gamma table: %d\n", err); goto done; } if (mac_entries == win_entries) { for (win_entry = 0; win_entry < win_entries; win_entry++) { r->red[win_entry] = red[win_entry] * 65535 + 0.5; r->green[win_entry] = green[win_entry] * 65535 + 0.5; r->blue[win_entry] = blue[win_entry] * 65535 + 0.5; } } else { for (win_entry = 0; win_entry < win_entries; win_entry++) { double mac_pos = win_entry * (mac_entries - 1) / (double)(win_entries - 1); int mac_entry = mac_pos; double red_value, green_value, blue_value; if (mac_entry == mac_entries - 1) { red_value = red[mac_entry]; green_value = green[mac_entry]; blue_value = blue[mac_entry]; } else { double distance = mac_pos - mac_entry; red_value = red[mac_entry] * (1 - distance) + red[mac_entry + 1] * distance; green_value = green[mac_entry] * (1 - distance) + green[mac_entry + 1] * distance; blue_value = blue[mac_entry] * (1 - distance) + blue[mac_entry + 1] * distance; } r->red[win_entry] = red_value * 65535 + 0.5; r->green[win_entry] = green_value * 65535 + 0.5; r->blue[win_entry] = blue_value * 65535 + 0.5; } } ret = TRUE; done: HeapFree(GetProcessHeap(), 0, red); macdrv_free_displays(displays); return ret; }