diff options
Diffstat (limited to 'src/location-corelocation.m')
-rw-r--r-- | src/location-corelocation.m | 311 |
1 files changed, 0 insertions, 311 deletions
diff --git a/src/location-corelocation.m b/src/location-corelocation.m deleted file mode 100644 index 1b94137..0000000 --- a/src/location-corelocation.m +++ /dev/null @@ -1,311 +0,0 @@ -/*- - * redshift-ng - Automatically adjust display colour temperature according the Sun - * - * Copyright (c) 2009-2018 Jon Lund Steffensen <jonlst@gmail.com> - * Copyright (c) 2014-2016, 2025 Mattias Andrée <m@maandree.se> - * - * redshift-ng 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-ng 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-ng. If not, see <http://www.gnu.org/licenses/>. - */ -#include "common.h" - -#import <Foundation/Foundation.h> -#import <CoreLocation/CoreLocation.h> - - -/** - * Location data - */ -struct location_data { - /** - * The user's geographical location - */ - struct location location; - - /** - * Whether the location provider is available - */ - int available; - - /** - * Whether an unrecoverable error has occurred - */ - int error; -}; - - -struct location_state { - /** - * Slave thread, used to receive location updates - */ - NSThread *thread; - - /** - * Read-end of piped used to send location data - * from the slave thread to the master thread - */ - int pipe_fd_read; - - /** - * Write-end of piped used to send location data - * from the slave thread to the master thread - */ - int pipe_fd_write; - - /** - * Location data available from the slave thread - */ - struct location_data data; - - /** - * Location data sent to the master thread - */ - struct location_data saved_data; -}; - - -@interface LocationDelegate : NSObject <CLLocationManagerDelegate> - @property (strong, nonatomic) CLLocationManager *locationManager; - @property (nonatomic) struct location_state *state; -@end - - -static void -send_data(struct location_state *state) -{ - while (write(state->pipe_fd_write, &state->data, sizeof(state->data)) == -1 && errno == EINTR); -} - - -@implementation LocationDelegate; - -- (void)start -{ - CLAuthorizationStatus authStatus; - - self.locationManager = [[CLLocationManager alloc] init]; - self.locationManager.delegate = self; - self.locationManager.distanceFilter = 50000; - self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer; - - authStatus = [CLLocationManager authorizationStatus]; - - if (authStatus != kCLAuthorizationStatusNotDetermined && - authStatus != kCLAuthorizationStatusAuthorized) { - weprintf(_("Not authorized to obtain location from CoreLocation.")); - [self markError]; - } else { - [self.locationManager startUpdatingLocation]; - } -} - -- (void)markError -{ - self.state->data.error = 1; - send_data(self.state); -} - -- (void)markUnavailable -{ - self.state->data.available = 0; - send_data(self.state); -} - -- (void)locationManager:(CLLocationManager *)manager - didUpdateLocations:(NSArray *)locations -{ - CLLocation *newLocation = [locations firstObject]; - - self.state->data.location.lat = newLocation.coordinate.latitude; - self.state->data.location.lon = newLocation.coordinate.longitude; - self.state->data.available = 1; - send_data(self.state); -} - -- (void)locationManager:(CLLocationManager *)manager - didFailWithError:(NSError *)error -{ - weprintf(_("Error obtaining location from CoreLocation: %s"), [[error localizedDescription] UTF8String]); - if ([error code] == kCLErrorDenied) - [self markError]; - else - [self markUnavailable]; -} - -- (void)locationManager:(CLLocationManager *)manager - didChangeAuthorizationStatus:(CLAuthorizationStatus)status -{ - if (status == kCLAuthorizationStatusNotDetermined) { - weprintf(_("Waiting for authorization to obtain location...")); - } else if (status != kCLAuthorizationStatusAuthorized) { - weprintf(_("Request for location was not authorized!")); - [self markError]; - } -} - -@end - - -// Callback when the pipe is closed. -// -// Stops the run loop causing the thread to end. -static void -pipe_close_callback(CFFileDescriptorRef fdref, CFOptionFlags callBackTypes, void *info) -{ - CFFileDescriptorInvalidate(fdref); - CFRelease(fdref); - - CFRunLoopStop(CFRunLoopGetCurrent()); -} - - -@interface LocationThread : NSThread - @property (nonatomic) struct location_state *state; -@end - - -@implementation LocationThread; - -// Run loop for location provider thread. -- (void)main -{ - @autoreleasepool { - LocationDelegate *locationDelegate; - CFFileDescriptorRef fdref; - CFRunLoopSourceRef source; - - locationDelegate = [[LocationDelegate alloc] init]; - locationDelegate.state = self.state; - - // Start the location delegate on the run loop in this thread. - [locationDelegate performSelector:@selector(start) withObject:nil afterDelay:0]; - - // Create a callback that is triggered when the pipe is closed. This will - // trigger the main loop to quit and the thread to stop. - fdref = CFFileDescriptorCreate(kCFAllocatorDefault, self.state->pipe_fd_write, - false, pipe_close_callback, NULL); - CFFileDescriptorEnableCallBacks(fdref, kCFFileDescriptorReadCallBack); - source = CFFileDescriptorCreateRunLoopSource(kCFAllocatorDefault, fdref, 0); - CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode); - - // Run the loop - CFRunLoopRun(); - - close(self.state->pipe_fd_write); - } -} - -@end - - -static int -corelocation_create(struct location_state **state_out) -{ - *state_out = emalloc(sizeof(**state_out)); - return 0; -} - - -static int -corelocation_start(struct location_state *state) -{ - LocationThread *thread; - int pipefds[2]; - - state->pipe_fd_read = -1; - state->pipe_fd_write = -1; - - state->data.available = 0; - state->data.error = 0; - state->data.location.lat = 0; - state->data.location.lon = 0; - state->saved_data = state->data; - - pipe_rdnonblock(pipefds); - state->pipe_fd_read = pipefds[0]; - state->pipe_fd_write = pipefds[1]; - - send_data(state); /* TODO why? */ - - thread = [[LocationThread alloc] init]; - thread.state = state; - [thread start]; - state->thread = thread; - - return 0; -} - - -static void -corelocation_free(struct location_state *state) -{ - if (state->pipe_fd_read >= 0) - close(state->pipe_fd_read); - free(state); -} - - -static void -corelocation_print_help(void) -{ - printf(_("Use the location as discovered by the Corelocation provider.\n")); - printf("\n"); -} - - -static int -corelocation_set_option(struct location_state *state, const char *key, const char *value) -{ - (void) state; - (void) value; - weprintf(_("Unknown provider parameter: `%s'."), key); - return -1; -} - - -static int -corelocation_get_fd(struct location_state *state) -{ - return state->pipe_fd_read; -} - - -static int -corelocation_fetch(struct location_state *state, struct location *location_out, int *available_out) -{ - struct location_data data; - ssize_t r; - - for (;;) { - r = read(state->pipe_fd_read, &data, sizeof(data)); - if (r == (ssize_t)sizeof(data)) { - state->saved_data = data; - } else if (r > 0) { - /* writes of 512 bytes or less are always atomic on pipes */ - weprintf("read <pipe>: %s", _("Unexpected message size")); - } else if (!r || errno == EAGAIN) { - break; - } else if (errno != EINTR) { - weprintf("read <pipe>:"); - state->saved_data.error = 1; - break; - } - } - - *location_out = state->saved_data.location; - *available_out = state->saved_data.available; - return state->saved_data.error ? -1 : 0; -} - - -const location_provider_t corelocation_location_provider = LOCATION_PROVIDER_INIT("corelocation", corelocation); |