aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJon Lund Steffensen <jonlst@gmail.com>2014-12-16 06:41:22 +0100
committerJon Lund Steffensen <jonlst@gmail.com>2014-12-16 06:41:22 +0100
commit003025f5a3f4f9678279cd5bd985d0d32d1a4a48 (patch)
tree3a3e69b2711bfbde5c557192bf10ea544a4617a7 /src
parentMerge pull request #145 from jonls/appdata-xml (diff)
parentAdd CoreLocation (OSX) location provider (diff)
downloadredshift-ng-003025f5a3f4f9678279cd5bd985d0d32d1a4a48.tar.gz
redshift-ng-003025f5a3f4f9678279cd5bd985d0d32d1a4a48.tar.bz2
redshift-ng-003025f5a3f4f9678279cd5bd985d0d32d1a4a48.tar.xz
Merge pull request #140 from jonls/osx-support
OSX support. Adds gamma adjustment method `quartz` and location provider `corelocation`.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am23
-rw-r--r--src/colorramp.c28
-rw-r--r--src/colorramp.h5
-rw-r--r--src/gamma-quartz.c146
-rw-r--r--src/gamma-quartz.h44
-rw-r--r--src/location-corelocation.h38
-rw-r--r--src/location-corelocation.m163
-rw-r--r--src/redshift.c37
8 files changed, 480 insertions, 4 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index eca9217..8d11a03 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -21,6 +21,7 @@ EXTRA_redshift_SOURCES = \
gamma-drm.c gamma-drm.h \
gamma-randr.c gamma-randr.h \
gamma-vidmode.c gamma-vidmode.h \
+ gamma-quartz.c gamma-quartz.h \
gamma-w32gdi.c gamma-w32gdi.h \
location-geoclue.c location-geoclue.h
@@ -51,6 +52,13 @@ redshift_LDADD += \
$(XF86VM_LIBS) $(XF86VM_CFLAGS)
endif
+if ENABLE_QUARTZ
+redshift_SOURCES += gamma-quartz.c gamma-quartz.h
+AM_CFLAGS += $(QUARTZ_CFLAGS)
+redshift_LDADD += \
+ $(QUARTZ_LIBS) $(QUARTZ_CFLAGS)
+endif
+
if ENABLE_WINGDI
redshift_SOURCES += gamma-w32gdi.c gamma-w32gdi.h
redshift_LDADD += -lgdi32
@@ -74,3 +82,18 @@ AM_CFLAGS += \
redshift_LDADD += \
$(GEOCLUE2_LIBS) $(GEOCLUE2_CFLAGS)
endif
+
+# Build CoreLocation module as a separate convenience
+# library since it is using a separate compiler
+# (Objective C).
+
+if ENABLE_CORELOCATION
+noinst_LTLIBRARIES = liblocation-corelocation.la
+liblocation_corelocation_la_SOURCES = \
+ location-corelocation.m location-corelocation.h
+liblocation_corelocation_la_OBJCFLAGS = \
+ $(CORELOCATION_CFLAGS)
+liblocation_corelocation_la_LIBADD = \
+ $(CORELOCATION_CFLAGS) $(CORELOCATION_LIBS)
+redshift_LDADD += liblocation-corelocation.la
+endif
diff --git a/src/colorramp.c b/src/colorramp.c
index f1988d4..3521195 100644
--- a/src/colorramp.c
+++ b/src/colorramp.c
@@ -14,7 +14,7 @@
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) 2013 Jon Lund Steffensen <jonlst@gmail.com>
+ Copyright (c) 2013-2014 Jon Lund Steffensen <jonlst@gmail.com>
Copyright (c) 2013 Ingo Thies <ithies@astro.uni-bonn.de>
*/
@@ -280,6 +280,9 @@ interpolate_color(float a, const float *c1, const float *c2, float *c)
c[2] = (1.0-a)*c1[2] + a*c2[2];
}
+/* Helper macro used in the fill functions */
+#define F(Y, C) pow((Y) * brightness * white_point[C], 1.0/gamma[C])
+
void
colorramp_fill(uint16_t *gamma_r, uint16_t *gamma_g, uint16_t *gamma_b,
int size, int temp, float brightness, const float gamma[3])
@@ -291,11 +294,30 @@ colorramp_fill(uint16_t *gamma_r, uint16_t *gamma_g, uint16_t *gamma_b,
interpolate_color(alpha, &blackbody_color[temp_index],
&blackbody_color[temp_index+3], white_point);
-#define F(Y, C) pow((Y) * brightness * white_point[C], 1.0/gamma[C])
-
for (int i = 0; i < size; i++) {
gamma_r[i] = F((float)i/size, 0) * (UINT16_MAX+1);
gamma_g[i] = F((float)i/size, 1) * (UINT16_MAX+1);
gamma_b[i] = F((float)i/size, 2) * (UINT16_MAX+1);
}
}
+
+void
+colorramp_fill_float(float *gamma_r, float *gamma_g, float *gamma_b,
+ int size, int temp, float brightness,
+ const float gamma[3])
+{
+ /* Approximate white point */
+ float white_point[3];
+ float alpha = (temp % 100) / 100.0;
+ int temp_index = ((temp - 1000) / 100)*3;
+ interpolate_color(alpha, &blackbody_color[temp_index],
+ &blackbody_color[temp_index+3], white_point);
+
+ for (int i = 0; i < size; i++) {
+ gamma_r[i] = F((float)i/size, 0);
+ gamma_g[i] = F((float)i/size, 1);
+ gamma_b[i] = F((float)i/size, 2);
+ }
+}
+
+#undef F
diff --git a/src/colorramp.h b/src/colorramp.h
index dd0fa97..f8df478 100644
--- a/src/colorramp.h
+++ b/src/colorramp.h
@@ -14,7 +14,7 @@
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>
+ Copyright (c) 2010-2014 Jon Lund Steffensen <jonlst@gmail.com>
*/
#ifndef REDSHIFT_COLORRAMP_H
@@ -24,5 +24,8 @@
void colorramp_fill(uint16_t *gamma_r, uint16_t *gamma_g, uint16_t *gamma_b,
int size, int temp, float brightness, const float gamma[3]);
+void colorramp_fill_float(float *gamma_r, float *gamma_g, float *gamma_b,
+ int size, int temp, float brightness,
+ const float gamma[3]);
#endif /* ! REDSHIFT_COLORRAMP_H */
diff --git a/src/gamma-quartz.c b/src/gamma-quartz.c
new file mode 100644
index 0000000..2f439da
--- /dev/null
+++ b/src/gamma-quartz.c
@@ -0,0 +1,146 @@
+/* gamma-quartz.c -- Quartz (OSX) gamma adjustment
+ 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) 2014 Jon Lund Steffensen <jonlst@gmail.com>
+*/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <ApplicationServices/ApplicationServices.h>
+
+#ifdef ENABLE_NLS
+# include <libintl.h>
+# define _(s) gettext(s)
+#else
+# define _(s) s
+#endif
+
+#include "gamma-quartz.h"
+#include "colorramp.h"
+
+
+int
+quartz_init(quartz_state_t *state)
+{
+ return 0;
+}
+
+int
+quartz_start(quartz_state_t *state)
+{
+ return 0;
+}
+
+void
+quartz_restore(quartz_state_t *state)
+{
+ CGDisplayRestoreColorSyncSettings();
+}
+
+void
+quartz_free(quartz_state_t *state)
+{
+}
+
+void
+quartz_print_help(FILE *f)
+{
+ fputs(_("Adjust gamma ramps on OSX using Quartz.\n"), f);
+ fputs("\n", f);
+}
+
+int
+quartz_set_option(quartz_state_t *state, const char *key, const char *value)
+{
+ fprintf(stderr, _("Unknown method parameter: `%s'.\n"), key);
+ return -1;
+}
+
+static void
+quartz_set_temperature_for_display(CGDirectDisplayID display, int temp,
+ float brightness, const float gamma[3])
+{
+ uint32_t ramp_size = CGDisplayGammaTableCapacity(display);
+ if (ramp_size == 0) {
+ fprintf(stderr, _("Gamma ramp size too small: %i\n"),
+ ramp_size);
+ return;
+ }
+
+ /* Create new gamma ramps */
+ float *gamma_ramps = malloc(3*ramp_size*sizeof(float));
+ if (gamma_ramps == NULL) {
+ perror("malloc");
+ return;
+ }
+
+ float *gamma_r = &gamma_ramps[0*ramp_size];
+ float *gamma_g = &gamma_ramps[1*ramp_size];
+ float *gamma_b = &gamma_ramps[2*ramp_size];
+
+ colorramp_fill_float(gamma_r, gamma_g, gamma_b, ramp_size,
+ temp, brightness, gamma);
+
+ CGError error =
+ CGSetDisplayTransferByTable(display, ramp_size,
+ gamma_r, gamma_g, gamma_b);
+ if (error != kCGErrorSuccess) {
+ free(gamma_ramps);
+ return;
+ }
+
+ free(gamma_ramps);
+}
+
+int
+quartz_set_temperature(quartz_state_t *state, int temp, float brightness,
+ const float gamma[3])
+{
+ int r;
+ CGError error;
+ uint32_t display_count;
+
+ error = CGGetOnlineDisplayList(0, NULL, &display_count);
+ if (error != kCGErrorSuccess) return -1;
+
+ CGDirectDisplayID* displays =
+ malloc(sizeof(CGDirectDisplayID)*display_count);
+ if (displays == NULL) {
+ perror("malloc");
+ return -1;
+ }
+
+ error = CGGetOnlineDisplayList(display_count, displays,
+ &display_count);
+ if (error != kCGErrorSuccess) {
+ free(displays);
+ return -1;
+ }
+
+ for (int i = 0; i < display_count; i++) {
+ quartz_set_temperature_for_display(displays[i], temp,
+ brightness, gamma);
+ }
+
+ free(displays);
+
+ return 0;
+}
diff --git a/src/gamma-quartz.h b/src/gamma-quartz.h
new file mode 100644
index 0000000..c8bfef7
--- /dev/null
+++ b/src/gamma-quartz.h
@@ -0,0 +1,44 @@
+/* gamma-quartz.h -- Quartz (OSX) 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) 2014 Jon Lund Steffensen <jonlst@gmail.com>
+*/
+
+#ifndef REDSHIFT_GAMMA_QUARTZ_H
+#define REDSHIFT_GAMMA_QUARTZ_H
+
+#include "redshift.h"
+
+
+typedef struct {
+ int dummy;
+} quartz_state_t;
+
+
+int quartz_init(quartz_state_t *state);
+int quartz_start(quartz_state_t *state);
+void quartz_free(quartz_state_t *state);
+
+void quartz_print_help(FILE *f);
+int quartz_set_option(quartz_state_t *state, const char *key,
+ const char *value);
+
+void quartz_restore(quartz_state_t *state);
+int quartz_set_temperature(quartz_state_t *state, int temp, float brightness,
+ const float gamma[3]);
+
+
+#endif /* ! REDSHIFT_GAMMA_QUARTZ_H */
diff --git a/src/location-corelocation.h b/src/location-corelocation.h
new file mode 100644
index 0000000..58dddd7
--- /dev/null
+++ b/src/location-corelocation.h
@@ -0,0 +1,38 @@
+/* location-corelocation.h -- CoreLocation (OSX) location provider 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) 2014 Jon Lund Steffense <jonlst@gmail.com>
+*/
+
+#ifndef REDSHIFT_LOCATION_CORELOCATION_H
+#define REDSHIFT_LOCATION_CORELOCATION_H
+
+#include <stdio.h>
+
+
+int location_corelocation_init(void *state);
+int location_corelocation_start(void *state);
+void location_corelocation_free(void *state);
+
+void location_corelocation_print_help(FILE *f);
+int location_corelocation_set_option(void *state,
+ const char *key, const char *value);
+
+int location_corelocation_get_location(void *state,
+ float *lat, float *lon);
+
+
+#endif /* ! REDSHIFT_LOCATION_CORELOCATION_H */
diff --git a/src/location-corelocation.m b/src/location-corelocation.m
new file mode 100644
index 0000000..626949c
--- /dev/null
+++ b/src/location-corelocation.m
@@ -0,0 +1,163 @@
+/* location-corelocation.m -- CoreLocation (OSX) location provider 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) 2014 Jon Lund Steffensen <jonlst@gmail.com>
+*/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#import <Foundation/Foundation.h>
+#import <CoreLocation/CoreLocation.h>
+
+#include "location-corelocation.h"
+
+#include <stdio.h>
+
+#ifdef ENABLE_NLS
+# include <libintl.h>
+# define _(s) gettext(s)
+#else
+# define _(s) s
+#endif
+
+
+@interface Delegate : NSObject <CLLocationManagerDelegate>
+@property (strong, nonatomic) CLLocationManager *locationManager;
+@property (nonatomic) BOOL success;
+@property (nonatomic) float latitude;
+@property (nonatomic) float longitude;
+@end
+
+@implementation Delegate;
+
+- (void)start
+{
+ self.locationManager = [[CLLocationManager alloc] init];
+ self.locationManager.delegate = self;
+
+ CLAuthorizationStatus authStatus =
+ [CLLocationManager authorizationStatus];
+
+ if (authStatus != kCLAuthorizationStatusNotDetermined &&
+ authStatus != kCLAuthorizationStatusAuthorized) {
+ fputs(_("Not authorized to obtain location"
+ "from CoreLocation.\n"), stderr);
+ CFRunLoopStop(CFRunLoopGetCurrent());
+ }
+
+ [self.locationManager startUpdatingLocation];
+}
+
+- (void)stop
+{
+ [self.locationManager stopUpdatingLocation];
+ CFRunLoopStop(CFRunLoopGetCurrent());
+}
+
+- (void)locationManager:(CLLocationManager *)manager
+ didUpdateLocations:(NSArray *)locations
+{
+ CLLocation *newLocation = [locations firstObject];
+ self.latitude = newLocation.coordinate.latitude;
+ self.longitude = newLocation.coordinate.longitude;
+ self.success = YES;
+
+ [self stop];
+}
+
+- (void)locationManager:(CLLocationManager *)manager
+ didFailWithError:(NSError *)error
+{
+ fprintf(stderr, _("Error obtaining location from CoreLocation: %s\n"),
+ [[error localizedDescription] UTF8String]);
+ [self stop];
+}
+
+- (void)locationManager:(CLLocationManager *)manager
+ didChangeAuthorizationStatus:(CLAuthorizationStatus)status
+{
+ if (status == kCLAuthorizationStatusNotDetermined) {
+ fputs(_("Waiting for authorization to obtain location...\n"),
+ stderr);
+ } else if (status != kCLAuthorizationStatusAuthorized) {
+ fputs(_("Request for location was not authorized!\n"),
+ stderr);
+ [self stop];
+ }
+}
+
+@end
+
+
+int
+location_corelocation_init(void *state)
+{
+ return 0;
+}
+
+int
+location_corelocation_start(void *state)
+{
+ return 0;
+}
+
+void
+location_corelocation_free(void *state)
+{
+}
+
+void
+location_corelocation_print_help(FILE *f)
+{
+ fputs(_("Use the location as discovered by the Corelocation provider.\n"), f);
+ fputs("\n", f);
+
+ fputs(_("NOTE: currently redshift doesn't recheck CoreLocation once started,\n"
+ "which means it has to be restarted to take notice after travel.\n"),
+ f);
+ fputs("\n", f);
+}
+
+int
+location_corelocation_set_option(void *state,
+ const char *key, const char *value)
+{
+ fprintf(stderr, _("Unknown method parameter: `%s'.\n"), key);
+ return -1;
+}
+
+int
+location_corelocation_get_location(void *state,
+ float *lat, float *lon)
+{
+ int result = -1;
+
+ @autoreleasepool {
+ Delegate *delegate = [[Delegate alloc] init];
+ [delegate performSelectorOnMainThread:@selector(start) withObject:nil waitUntilDone:NO];
+ CFRunLoopRun();
+
+ if (delegate.success) {
+ *lat = delegate.latitude;
+ *lon = delegate.longitude;
+ result = 0;
+ }
+ }
+
+ return result;
+}
diff --git a/src/redshift.c b/src/redshift.c
index 0c9a6bd..818db4e 100644
--- a/src/redshift.c
+++ b/src/redshift.c
@@ -65,6 +65,10 @@
# include "gamma-vidmode.h"
#endif
+#ifdef ENABLE_QUARTZ
+# include "gamma-quartz.h"
+#endif
+
#ifdef ENABLE_WINGDI
# include "gamma-w32gdi.h"
#endif
@@ -80,6 +84,10 @@
# include "location-geoclue2.h"
#endif
+#ifdef ENABLE_CORELOCATION
+# include "location-corelocation.h"
+#endif
+
/* Union of state data for gamma adjustment methods */
typedef union {
@@ -92,6 +100,9 @@ typedef union {
#ifdef ENABLE_VIDMODE
vidmode_state_t vidmode;
#endif
+#ifdef ENABLE_QUARTZ
+ quartz_state_t quartz;
+#endif
#ifdef ENABLE_WINGDI
w32gdi_state_t w32gdi;
#endif
@@ -136,6 +147,18 @@ static const gamma_method_t gamma_methods[] = {
(gamma_method_set_temperature_func *)vidmode_set_temperature
},
#endif
+#ifdef ENABLE_QUARTZ
+ {
+ "quartz", 1,
+ (gamma_method_init_func *)quartz_init,
+ (gamma_method_start_func *)quartz_start,
+ (gamma_method_free_func *)quartz_free,
+ (gamma_method_print_help_func *)quartz_print_help,
+ (gamma_method_set_option_func *)quartz_set_option,
+ (gamma_method_restore_func *)quartz_restore,
+ (gamma_method_set_temperature_func *)quartz_set_temperature
+ },
+#endif
#ifdef ENABLE_WINGDI
{
"wingdi", 1,
@@ -201,6 +224,20 @@ static const location_provider_t location_providers[] = {
location_geoclue2_get_location
},
#endif
+#ifdef ENABLE_CORELOCATION
+ {
+ "corelocation",
+ (location_provider_init_func *)location_corelocation_init,
+ (location_provider_start_func *)location_corelocation_start,
+ (location_provider_free_func *)location_corelocation_free,
+ (location_provider_print_help_func *)
+ location_corelocation_print_help,
+ (location_provider_set_option_func *)
+ location_corelocation_set_option,
+ (location_provider_get_location_func *)
+ location_corelocation_get_location
+ },
+#endif
{
"manual",
(location_provider_init_func *)location_manual_init,