systemtime.c: Portably read current time on posix and windows.
w32gdi.c: Implements gamma ramp method for Windows GDI API. Use double as a cross platform time representation. Add WinGDI as a selectable method (currently limitied to minimum 4500K). Fix a bug where redshift would crash if RANDR failed and VidMode wasn't compiled in.
This commit is contained in:
+26
-2
@@ -20,6 +20,8 @@ PKG_CHECK_MODULES([XCB], [xcb], [have_xcb=yes], [have_xcb=no])
|
||||
PKG_CHECK_MODULES([XCB_RANDR], [xcb-randr],
|
||||
[have_xcb_randr=yes], [have_xcb_randr=no])
|
||||
|
||||
AC_CHECK_HEADER([windows.h], [have_windows_h=yes], [have_windows_h=no])
|
||||
|
||||
# Check for Python
|
||||
AM_PATH_PYTHON([2.6], [have_python=yes], [have_python=no])
|
||||
|
||||
@@ -67,9 +69,31 @@ AS_IF([test "x$enable_vidmode" != xno], [
|
||||
])
|
||||
AM_CONDITIONAL([ENABLE_VIDMODE], [test "x$enable_vidmode" != xno])
|
||||
|
||||
# Check Windows GDI method
|
||||
AC_MSG_CHECKING([whether to enable WinGDI method])
|
||||
AC_ARG_ENABLE([wingdi], [AC_HELP_STRING([--enable-wingdi],
|
||||
[enable WinGDI method])],
|
||||
[enable_wingdi=$enableval],[enable_wingdi=maybe])
|
||||
AS_IF([test "x$enable_wingdi" != xno], [
|
||||
AS_IF([test $have_windows_h = yes], [
|
||||
AC_DEFINE([ENABLE_WINGDI], 1,
|
||||
[Define to 1 to enable WinGDI method])
|
||||
AC_MSG_RESULT([yes])
|
||||
], [
|
||||
AC_MSG_RESULT([missing dependencies])
|
||||
AS_IF([test "x$enable_wingdi" = xyes], [
|
||||
AC_MSG_ERROR([missing Windows API headers for WinGDI method])
|
||||
])
|
||||
enable_wingdi=no
|
||||
])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
AM_CONDITIONAL([ENABLE_WINGDI], [test "x$enable_wingdi" != xno])
|
||||
|
||||
# Check that at least one method is enabled
|
||||
AS_IF([test "x$enable_randr" = xno -a "x$enable_vidmode" = xno], [
|
||||
AC_MSG_ERROR([either RANDR or VidMode must be enabled])
|
||||
AS_IF([test "x$enable_randr" = xno -a "x$enable_vidmode" = xno -a "x$enable_wingdi" = xno], [
|
||||
AC_MSG_ERROR([either RANDR, VidMode or WinGDI must be enabled])
|
||||
])
|
||||
|
||||
# Check for GTK+ status icon
|
||||
|
||||
+9
-2
@@ -11,11 +11,13 @@ bin_PROGRAMS = redshift
|
||||
redshift_SOURCES = \
|
||||
redshift.c \
|
||||
colorramp.c colorramp.h \
|
||||
solar.c solar.h
|
||||
solar.c solar.h \
|
||||
systemtime.c systemtime.h
|
||||
|
||||
EXTRA_redshift_SOURCES = \
|
||||
randr.c randr.h \
|
||||
vidmode.c vidmode.h
|
||||
vidmode.c vidmode.h \
|
||||
w32gdi.c w32gdi.h
|
||||
|
||||
AM_CFLAGS =
|
||||
redshift_LDADD = @LIBINTL@
|
||||
@@ -36,3 +38,8 @@ redshift_LDADD += \
|
||||
$(X11_LIBS) $(X11_CFLAGS) \
|
||||
$(XF86VM_LIBS) $(XF86VM_CFLAGS)
|
||||
endif
|
||||
|
||||
if ENABLE_WINGDI
|
||||
redshift_SOURCES += w32gdi.c w32gdi.h
|
||||
redshift_LDADD += -lgdi32
|
||||
endif
|
||||
|
||||
+93
-24
@@ -28,20 +28,30 @@
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <locale.h>
|
||||
#include <sys/signal.h>
|
||||
|
||||
#include <libintl.h>
|
||||
#define _(s) gettext(s)
|
||||
#ifdef HAVE_SYS_SIGNAL_H
|
||||
# include <sys/signal.h>
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
# define _(s) gettext(s)
|
||||
#else
|
||||
# define _(s) s
|
||||
#endif
|
||||
|
||||
#include "solar.h"
|
||||
#include "systemtime.h"
|
||||
|
||||
|
||||
#define MIN(x,y) ((x) < (y) ? (x) : (y))
|
||||
#define MAX(x,y) ((x) > (y) ? (x) : (y))
|
||||
|
||||
|
||||
#if !(defined(ENABLE_RANDR) || defined(ENABLE_VIDMODE))
|
||||
# error "At least one of RANDR or VidMode must be enabled."
|
||||
#if !(defined(ENABLE_RANDR) || \
|
||||
defined(ENABLE_VIDMODE) || \
|
||||
defined(ENABLE_WINGDI))
|
||||
# error "At least one of RANDR, VidMode or WinGDI must be enabled."
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_RANDR
|
||||
@@ -52,6 +62,10 @@
|
||||
# include "vidmode.h"
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_WINGDI
|
||||
# include "w32gdi.h"
|
||||
#endif
|
||||
|
||||
|
||||
/* Union of state data for gamma adjustment methods */
|
||||
typedef union {
|
||||
@@ -61,6 +75,9 @@ typedef union {
|
||||
#ifdef ENABLE_VIDMODE
|
||||
vidmode_state_t vidmode;
|
||||
#endif
|
||||
#ifdef ENABLE_WINGDI
|
||||
w32gdi_state_t w32gdi;
|
||||
#endif
|
||||
} gamma_state_t;
|
||||
|
||||
|
||||
@@ -128,6 +145,11 @@ gamma_state_restore(gamma_state_t *state, int use_randr)
|
||||
case 1:
|
||||
randr_restore(&state->randr);
|
||||
break;
|
||||
#endif
|
||||
#ifdef ENABLE_WINGDI
|
||||
case 2:
|
||||
w32gdi_restore(&state->w32gdi);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -146,6 +168,11 @@ gamma_state_free(gamma_state_t *state, int use_randr)
|
||||
case 1:
|
||||
randr_free(&state->randr);
|
||||
break;
|
||||
#endif
|
||||
#ifdef ENABLE_WINGDI
|
||||
case 2:
|
||||
w32gdi_free(&state->w32gdi);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -163,6 +190,10 @@ gamma_state_set_temperature(gamma_state_t *state, int use_randr,
|
||||
#ifdef ENABLE_RANDR
|
||||
case 1:
|
||||
return randr_set_temperature(&state->randr, temp, gamma);
|
||||
#endif
|
||||
#ifdef ENABLE_WINGDI
|
||||
case 2:
|
||||
return w32gdi_set_temperature(&state->w32gdi, temp, gamma);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -225,7 +256,7 @@ print_help(const char *program_name)
|
||||
fputs(_(" -g R:G:B\tAdditional gamma correction to apply\n"
|
||||
" -l LAT:LON\tYour current location\n"
|
||||
" -m METHOD\tMethod to use to set color temperature"
|
||||
" (RANDR or VidMode)\n"
|
||||
" (RANDR, VidMode or WinGDI)\n"
|
||||
" -o\t\tOne shot mode (do not continously adjust"
|
||||
" color temperature)\n"
|
||||
" -r\t\tDisable temperature transitions\n"
|
||||
@@ -346,6 +377,16 @@ main(int argc, char *argv[])
|
||||
" enabled at compile time.\n"),
|
||||
stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
#endif
|
||||
} else if (strcmp(optarg, "wingdi") == 0 ||
|
||||
strcmp(optarg, "WinGDI") == 0) {
|
||||
#ifdef ENABLE_WINGDI
|
||||
use_randr = 2;
|
||||
#else
|
||||
fputs(_("WinGDI method was not"
|
||||
" enabled at compile time.\n"),
|
||||
stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
#endif
|
||||
} else {
|
||||
/* TRANSLATORS: This refers to the method
|
||||
@@ -482,19 +523,47 @@ main(int argc, char *argv[])
|
||||
if (r < 0) {
|
||||
fputs(_("Initialization of VidMode failed.\n"),
|
||||
stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
if (use_randr < 0) {
|
||||
fputs(_("Trying other method...\n"), stderr);
|
||||
} else {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else {
|
||||
use_randr = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_WINGDI
|
||||
if (use_randr < 0 || use_randr == 2) {
|
||||
/* Initialize WinGDI state */
|
||||
r = w32gdi_init(&state.w32gdi);
|
||||
if (r < 0) {
|
||||
fputs(_("Initialization of WinGDI failed.\n"),
|
||||
stderr);
|
||||
if (use_randr < 0) {
|
||||
fputs(_("Trying other method...\n"), stderr);
|
||||
} else {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else {
|
||||
use_randr = 2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Failure if no methods were successful at this point. */
|
||||
if (use_randr < 0) {
|
||||
fputs(_("No more methods to try.\n"), stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (one_shot) {
|
||||
/* Current angular elevation of the sun */
|
||||
struct timespec now;
|
||||
r = clock_gettime(CLOCK_REALTIME, &now);
|
||||
double now;
|
||||
r = systemtime_get_time(&now);
|
||||
if (r < 0) {
|
||||
perror("clock_gettime");
|
||||
fputs(_("Unable to read system time.\n"), stderr);
|
||||
gamma_state_free(&state, use_randr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -522,7 +591,7 @@ main(int argc, char *argv[])
|
||||
}
|
||||
} else {
|
||||
/* Transition state */
|
||||
struct timespec short_trans_end;
|
||||
double short_trans_end = 0;
|
||||
int short_trans = 0;
|
||||
int short_trans_done = 0;
|
||||
|
||||
@@ -599,10 +668,11 @@ main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* Read timestamp */
|
||||
struct timespec now;
|
||||
r = clock_gettime(CLOCK_REALTIME, &now);
|
||||
double now;
|
||||
r = systemtime_get_time(&now);
|
||||
if (r < 0) {
|
||||
perror("clock_gettime");
|
||||
fputs(_("Unable to read system time.\n"),
|
||||
stderr);
|
||||
gamma_state_free(&state, use_randr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -610,11 +680,8 @@ main(int argc, char *argv[])
|
||||
/* Set up a new transition */
|
||||
if (short_trans_create) {
|
||||
if (transition) {
|
||||
memcpy(&short_trans_end, &now,
|
||||
sizeof(struct timespec));
|
||||
short_trans_end.tv_sec +=
|
||||
short_trans_len;
|
||||
|
||||
short_trans_end = now;
|
||||
short_trans_end += short_trans_len;
|
||||
short_trans = 1;
|
||||
short_trans_create = 0;
|
||||
} else {
|
||||
@@ -631,11 +698,8 @@ main(int argc, char *argv[])
|
||||
|
||||
/* Ongoing short transition */
|
||||
if (short_trans) {
|
||||
double start = now.tv_sec +
|
||||
now.tv_nsec / 1000000000.0;
|
||||
double end = short_trans_end.tv_sec +
|
||||
short_trans_end.tv_nsec /
|
||||
1000000000.0;
|
||||
double start = now;
|
||||
double end = short_trans_end;
|
||||
|
||||
if (start > end) {
|
||||
/* Transisiton done */
|
||||
@@ -691,8 +755,13 @@ main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* Sleep for a while */
|
||||
#ifndef _WIN32
|
||||
if (short_trans) usleep(100000);
|
||||
else usleep(5000000);
|
||||
#else /* ! _WIN32 */
|
||||
if (short_trans) Sleep(100);
|
||||
else Sleep(5000);
|
||||
#endif /* ! _WIN32 */
|
||||
}
|
||||
|
||||
/* Restore saved gamma ramps */
|
||||
|
||||
+22
-20
@@ -24,9 +24,9 @@
|
||||
Jean Meeus. */
|
||||
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "solar.h"
|
||||
#include "time.h"
|
||||
|
||||
#define RAD(x) ((x)*(M_PI/180))
|
||||
#define DEG(x) ((x)*(180/M_PI))
|
||||
@@ -46,23 +46,20 @@ static const double time_angle[] = {
|
||||
};
|
||||
|
||||
|
||||
/* Unix time from Julian day */
|
||||
static struct timespec
|
||||
timespec_from_jd(double jd)
|
||||
/* Unix epoch from Julian day */
|
||||
static double
|
||||
epoch_from_jd(double jd)
|
||||
{
|
||||
struct timespec t;
|
||||
double secs = 86400.0*(jd - 2440587.5);
|
||||
t.tv_sec = floor(secs);
|
||||
t.tv_nsec = (secs - t.tv_sec) * 1000000000.0;
|
||||
return t;
|
||||
return 86400.0*(jd - 2440587.5);
|
||||
}
|
||||
|
||||
/* Julian day from unix time */
|
||||
|
||||
|
||||
/* Julian day from unix epoch */
|
||||
static double
|
||||
jd_from_timespec(struct timespec t)
|
||||
jd_from_epoch(double t)
|
||||
{
|
||||
return (t.tv_sec / 86400.0) +
|
||||
(t.tv_nsec / 86400000000000.0) + 2440587.5;
|
||||
return (t / 86400.0) + 2440587.5;
|
||||
}
|
||||
|
||||
/* Julian centuries since J2000.0 from Julian day */
|
||||
@@ -287,18 +284,23 @@ solar_elevation_from_time(double t, double lat, double lon)
|
||||
return elevation_from_hour_angle(lat, decl, ha);
|
||||
}
|
||||
|
||||
/* Solar angular elevation at the given location and time.
|
||||
date: Seconds since unix epoch
|
||||
lat: Latitude of location
|
||||
lon: Longitude of location
|
||||
Return: Solar angular elevation in degrees */
|
||||
double
|
||||
solar_elevation(struct timespec date, double lat, double lon)
|
||||
solar_elevation(double date, double lat, double lon)
|
||||
{
|
||||
double jd = jd_from_timespec(date);
|
||||
double jd = jd_from_epoch(date);
|
||||
return DEG(solar_elevation_from_time(jcent_from_jd(jd), lat, lon));
|
||||
}
|
||||
|
||||
void
|
||||
solar_table_fill(struct timespec date, double lat, double lon, time_t *table)
|
||||
solar_table_fill(double date, double lat, double lon, double *table)
|
||||
{
|
||||
/* Calculate Julian day */
|
||||
double jd = jd_from_timespec(date);
|
||||
double jd = jd_from_epoch(date);
|
||||
|
||||
/* Calculate Julian day number */
|
||||
double jdn = round(jd);
|
||||
@@ -308,16 +310,16 @@ solar_table_fill(struct timespec date, double lat, double lon, time_t *table)
|
||||
double sol_noon = time_of_solar_noon(t, lon);
|
||||
double j_noon = jdn - 0.5 + sol_noon/1440.0;
|
||||
double t_noon = jcent_from_jd(j_noon);
|
||||
table[SOLAR_TIME_NOON] = timespec_from_jd(j_noon).tv_sec;
|
||||
table[SOLAR_TIME_NOON] = epoch_from_jd(j_noon);
|
||||
|
||||
/* Calculate solar midnight */
|
||||
table[SOLAR_TIME_MIDNIGHT] = timespec_from_jd(j_noon + 0.5).tv_sec;
|
||||
table[SOLAR_TIME_MIDNIGHT] = epoch_from_jd(j_noon + 0.5);
|
||||
|
||||
/* Calulate absoute time of other phenomena */
|
||||
for (int i = 2; i < SOLAR_TIME_MAX; i++) {
|
||||
double angle = time_angle[i];
|
||||
double offset =
|
||||
time_of_solar_elevation(t, t_noon, lat, lon, angle);
|
||||
table[i] = timespec_from_jd(jdn - 0.5 + offset/1440.0).tv_sec;
|
||||
table[i] = epoch_from_jd(jdn - 0.5 + offset/1440.0);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -20,7 +20,7 @@
|
||||
#ifndef _SOLAR_H
|
||||
#define _SOLAR_H
|
||||
|
||||
#include <time.h>
|
||||
#include "time.h"
|
||||
|
||||
/* Model of atmospheric refraction near horizon (in degrees). */
|
||||
#define SOLAR_ATM_REFRAC 0.833
|
||||
@@ -44,8 +44,8 @@ typedef enum {
|
||||
SOLAR_TIME_MAX
|
||||
} solar_time_t;
|
||||
|
||||
double solar_elevation(struct timespec date, double lat, double lon);
|
||||
void solar_table_fill(struct timespec date, double lat, double lon,
|
||||
time_t *table);
|
||||
|
||||
double solar_elevation(double date, double lat, double lon);
|
||||
void solar_table_fill(double date, double lat, double lon, double *table);
|
||||
|
||||
#endif /* ! _SOLAR_H */
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/* systemtime.c -- Portable system time source
|
||||
This file is part of Redshift.
|
||||
|
||||
Redshift is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Redshift is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Redshift. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright (c) 2010 Jon Lund Steffensen <jonlst@gmail.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <time.h>
|
||||
#endif
|
||||
|
||||
#include "systemtime.h"
|
||||
|
||||
int
|
||||
systemtime_get_time(double *t)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
struct timespec now;
|
||||
int r = clock_gettime(CLOCK_REALTIME, &now);
|
||||
if (r < 0) {
|
||||
perror("clock_gettime");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*t = now.tv_sec + (now.tv_nsec / 1000000000.0);
|
||||
#else /* _WIN32 */
|
||||
FILETIME now;
|
||||
ULARGE_INTEGER i;
|
||||
GetSystemTimeAsFileTime(&now);
|
||||
i.LowPart = now.dwLowDateTime;
|
||||
i.HighPart = now.dwHighDateTime;
|
||||
|
||||
/* FILETIME is tenths of microseconds since 1601-01-01 UTC */
|
||||
*t = (i.QuadPart / 10000000.0) - 11644473600.0;
|
||||
#endif /* _WIN32 */
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/* systemtime.h -- Portable system time header
|
||||
This file is part of Redshift.
|
||||
|
||||
Redshift is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Redshift is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Redshift. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright (c) 2010 Jon Lund Steffensen <jonlst@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef _REDSHIFT_SYSTEMTIME_H
|
||||
#define _REDSHIFT_SYSTEMTIME_H
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <time.h>
|
||||
#else
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
|
||||
int systemtime_get_time(double *now);
|
||||
|
||||
#endif /* ! _REDSHIFT_SYSTEMTIME_H */
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
/* w32gdi.c -- Windows GDI gamma adjustment source
|
||||
This file is part of Redshift.
|
||||
|
||||
Redshift is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Redshift is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Redshift. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright (c) 2010 Jon Lund Steffensen <jonlst@gmail.com>
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define WINVER 0x0500
|
||||
#include <windows.h>
|
||||
#include <wingdi.h>
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
# define _(s) gettext(s)
|
||||
#else
|
||||
# define _(s) s
|
||||
#endif
|
||||
|
||||
#include "w32gdi.h"
|
||||
#include "colorramp.h"
|
||||
|
||||
#define GAMMA_RAMP_SIZE 256
|
||||
|
||||
|
||||
int
|
||||
w32gdi_init(w32gdi_state_t *state)
|
||||
{
|
||||
BOOL r;
|
||||
|
||||
/* Open device context */
|
||||
state->hDC = GetDC(NULL);
|
||||
if (state->hDC == NULL) {
|
||||
fputs(_("Unable to open device context.\n"), stderr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check support for gamma ramps */
|
||||
int cmcap = GetDeviceCaps(state->hDC, COLORMGMTCAPS);
|
||||
if (cmcap != CM_GAMMA_RAMP) {
|
||||
fputs(_("Display device does not support gamma ramps.\n"),
|
||||
stderr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Allocate space for saved gamma ramps */
|
||||
state->saved_ramps = malloc(3*GAMMA_RAMP_SIZE*sizeof(WORD));
|
||||
if (state->saved_ramps == NULL) {
|
||||
perror("malloc");
|
||||
ReleaseDC(NULL, state->hDC);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Save current gamma ramps so we can restore them at program exit */
|
||||
r = GetDeviceGammaRamp(state->hDC, state->saved_ramps);
|
||||
if (!r) {
|
||||
fputs(_("Unable to save current gamma ramp.\n"), stderr);
|
||||
ReleaseDC(NULL, state->hDC);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
w32gdi_free(w32gdi_state_t *state)
|
||||
{
|
||||
/* Free saved ramps */
|
||||
free(state->saved_ramps);
|
||||
|
||||
/* Release device context */
|
||||
ReleaseDC(NULL, state->hDC);
|
||||
}
|
||||
|
||||
void
|
||||
w32gdi_restore(w32gdi_state_t *state)
|
||||
{
|
||||
/* Restore gamma ramps */
|
||||
BOOL r = SetDeviceGammaRamp(state->hDC, state->saved_ramps);
|
||||
if (!r) fputs(_("Unable to restore gamma ramps.\n"), stderr);
|
||||
}
|
||||
|
||||
int
|
||||
w32gdi_set_temperature(w32gdi_state_t *state, int temp, float gamma[3])
|
||||
{
|
||||
BOOL r;
|
||||
|
||||
/* Create new gamma ramps */
|
||||
WORD *gamma_ramps = malloc(3*GAMMA_RAMP_SIZE*sizeof(WORD));
|
||||
if (gamma_ramps == NULL) {
|
||||
perror("malloc");
|
||||
return -1;
|
||||
}
|
||||
|
||||
WORD *gamma_r = &gamma_ramps[0*GAMMA_RAMP_SIZE];
|
||||
WORD *gamma_g = &gamma_ramps[1*GAMMA_RAMP_SIZE];
|
||||
WORD *gamma_b = &gamma_ramps[2*GAMMA_RAMP_SIZE];
|
||||
|
||||
colorramp_fill(gamma_r, gamma_g, gamma_b, GAMMA_RAMP_SIZE,
|
||||
temp, gamma);
|
||||
|
||||
/* Set new gamma ramps */
|
||||
r = SetDeviceGammaRamp(state->hDC, gamma_ramps);
|
||||
if (!r) {
|
||||
fputs(_("Unable to set gamma ramps.\n"), stderr);
|
||||
free(gamma_ramps);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(gamma_ramps);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/* w32gdi.h -- Windows GDI gamma adjustment header
|
||||
This file is part of Redshift.
|
||||
|
||||
Redshift is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Redshift is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Redshift. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright (c) 2010 Jon Lund Steffensen <jonlst@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef _REDSHIFT_W32GDI_H
|
||||
#define _REDSHIFT_W32GDI_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <wingdi.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
HDC hDC;
|
||||
WORD *saved_ramps;
|
||||
} w32gdi_state_t;
|
||||
|
||||
int w32gdi_init(w32gdi_state_t *state);
|
||||
void w32gdi_free(w32gdi_state_t *state);
|
||||
void w32gdi_restore(w32gdi_state_t *state);
|
||||
int w32gdi_set_temperature(w32gdi_state_t *state, int temp, float gamma[3]);
|
||||
|
||||
#endif /* ! _REDSHIFT_W32GDI_H */
|
||||
Reference in New Issue
Block a user