aboutsummaryrefslogtreecommitdiffstats
path: root/src/location-corelocation.m
diff options
context:
space:
mode:
Diffstat (limited to 'src/location-corelocation.m')
-rw-r--r--src/location-corelocation.m277
1 files changed, 133 insertions, 144 deletions
diff --git a/src/location-corelocation.m b/src/location-corelocation.m
index bf899ee..b20d32d 100644
--- a/src/location-corelocation.m
+++ b/src/location-corelocation.m
@@ -15,6 +15,7 @@
along with Redshift. If not, see <http://www.gnu.org/licenses/>.
Copyright (c) 2014-2017 Jon Lund Steffensen <jonlst@gmail.com>
+ Copyright (c) 2025 Mattias Andrée <m@maandree.se>
*/
#include "common.h"
@@ -23,102 +24,96 @@
struct location_state {
- NSThread *thread;
- NSLock *lock;
- int pipe_fd_read;
- int pipe_fd_write;
- int available;
- int error;
- struct location location;
+ NSThread *thread;
+ NSLock *lock;
+ int pipe_fd_read;
+ int pipe_fd_write;
+ int available;
+ int error;
+ struct location location;
};
@interface LocationDelegate : NSObject <CLLocationManagerDelegate>
-@property (strong, nonatomic) CLLocationManager *locationManager;
-@property (nonatomic) struct location_state *state;
+ @property (strong, nonatomic) CLLocationManager *locationManager;
+ @property (nonatomic) struct location_state *state;
@end
@implementation LocationDelegate;
- (void)start
{
- self.locationManager = [[CLLocationManager alloc] init];
- self.locationManager.delegate = self;
- self.locationManager.distanceFilter = 50000;
- self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
-
- CLAuthorizationStatus authStatus =
- [CLLocationManager authorizationStatus];
-
- if (authStatus != kCLAuthorizationStatusNotDetermined &&
- authStatus != kCLAuthorizationStatusAuthorized) {
- fputs(_("Not authorized to obtain location"
- " from CoreLocation.\n"), stderr);
- [self markError];
- } else {
- [self.locationManager startUpdatingLocation];
- }
+ 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->lock lock];
+ [self.state->lock lock];
+ self.state->error = 1;
+ [self.state->lock unlock];
- self.state->error = 1;
-
- [self.state->lock unlock];
-
- pipeutils_signal(self.state->pipe_fd_write);
+ pipeutils_signal(self.state->pipe_fd_write);
}
- (void)markUnavailable
{
- [self.state->lock lock];
-
- self.state->available = 0;
-
- [self.state->lock unlock];
+ [self.state->lock lock];
+ self.state->available = 0;
+ [self.state->lock unlock];
- pipeutils_signal(self.state->pipe_fd_write);
+ pipeutils_signal(self.state->pipe_fd_write);
}
- (void)locationManager:(CLLocationManager *)manager
- didUpdateLocations:(NSArray *)locations
+ didUpdateLocations:(NSArray *)locations
{
- CLLocation *newLocation = [locations firstObject];
+ CLLocation *newLocation = [locations firstObject];
- [self.state->lock lock];
+ [self.state->lock lock];
- self.state->location.lat = newLocation.coordinate.latitude;
- self.state->location.lon = newLocation.coordinate.longitude;
- self.state->available = 1;
+ self.state->location.lat = newLocation.coordinate.latitude;
+ self.state->location.lon = newLocation.coordinate.longitude;
+ self.state->available = 1;
- [self.state->lock unlock];
+ [self.state->lock unlock];
- pipeutils_signal(self.state->pipe_fd_write);
+ pipeutils_signal(self.state->pipe_fd_write);
}
- (void)locationManager:(CLLocationManager *)manager
- didFailWithError:(NSError *)error
+ didFailWithError:(NSError *)error
{
- fprintf(stderr, _("Error obtaining location from CoreLocation: %s\n"),
- [[error localizedDescription] UTF8String]);
- if ([error code] == kCLErrorDenied) {
- [self markError];
- } else {
- [self markUnavailable];
- }
+ 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
+ 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 markError];
- }
+ if (status == kCLAuthorizationStatusNotDetermined) {
+ weprintf(_("Waiting for authorization to obtain location..."));
+ } else if (status != kCLAuthorizationStatusAuthorized) {
+ weprintf(_("Request for location was not authorized!"));
+ [self markError];
+ }
}
@end
@@ -128,18 +123,17 @@ struct location_state {
//
// Stops the run loop causing the thread to end.
static void
-pipe_close_callback(
- CFFileDescriptorRef fdref, CFOptionFlags callBackTypes, void *info)
+pipe_close_callback(CFFileDescriptorRef fdref, CFOptionFlags callBackTypes, void *info)
{
- CFFileDescriptorInvalidate(fdref);
- CFRelease(fdref);
+ CFFileDescriptorInvalidate(fdref);
+ CFRelease(fdref);
- CFRunLoopStop(CFRunLoopGetCurrent());
+ CFRunLoopStop(CFRunLoopGetCurrent());
}
@interface LocationThread : NSThread
-@property (nonatomic) struct location_state *state;
+ @property (nonatomic) struct location_state *state;
@end
@implementation LocationThread;
@@ -147,29 +141,30 @@ pipe_close_callback(
// Run loop for location provider thread.
- (void)main
{
- @autoreleasepool {
- LocationDelegate *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.
- CFFileDescriptorRef fdref = CFFileDescriptorCreate(
- kCFAllocatorDefault, self.state->pipe_fd_write, false,
- pipe_close_callback, NULL);
- CFFileDescriptorEnableCallBacks(fdref, kCFFileDescriptorReadCallBack);
- CFRunLoopSourceRef source = CFFileDescriptorCreateRunLoopSource(
- kCFAllocatorDefault, fdref, 0);
- CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
-
- // Run the loop
- CFRunLoopRun();
-
- close(self.state->pipe_fd_write);
- }
+ @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
@@ -178,103 +173,97 @@ pipe_close_callback(
static int
location_corelocation_init(struct location_state **state)
{
- *state = malloc(sizeof(struct location_state));
- if (*state == NULL) return -1;
- return 0;
+ *state = emalloc(sizeof(**state));
+ return 0;
}
static int
location_corelocation_start(struct location_state *state)
{
- state->pipe_fd_read = -1;
- state->pipe_fd_write = -1;
+ LocationThread *thread;
+ int pipefds[2];
- state->available = 0;
- state->error = 0;
- state->location.lat = 0;
- state->location.lon = 0;
+ state->pipe_fd_read = -1;
+ state->pipe_fd_write = -1;
- int pipefds[2];
- int r = pipeutils_create_nonblocking(pipefds);
- if (r < 0) {
- fputs(_("Failed to start CoreLocation provider!\n"), stderr);
- return -1;
- }
+ state->available = 0;
+ state->error = 0;
+ state->location.lat = 0;
+ state->location.lon = 0;
- state->pipe_fd_read = pipefds[0];
- state->pipe_fd_write = pipefds[1];
+ if (pipeutils_create_nonblocking(pipefds)) {
+ weprintf(_("Failed to start CoreLocation provider!"));
+ return -1;
+ }
- pipeutils_signal(state->pipe_fd_write);
+ state->pipe_fd_read = pipefds[0];
+ state->pipe_fd_write = pipefds[1];
- state->lock = [[NSLock alloc] init];
+ pipeutils_signal(state->pipe_fd_write);
- LocationThread *thread = [[LocationThread alloc] init];
- thread.state = state;
- [thread start];
- state->thread = thread;
+ state->lock = [[NSLock alloc] init];
- return 0;
+ thread = [[LocationThread alloc] init];
+ thread.state = state;
+ [thread start];
+ state->thread = thread;
+
+ return 0;
}
static void
location_corelocation_free(struct location_state *state)
{
- if (state->pipe_fd_read != -1) {
- close(state->pipe_fd_read);
- }
-
- free(state);
+ if (state->pipe_fd_read >= 0)
+ close(state->pipe_fd_read);
+ free(state);
}
static void
location_corelocation_print_help(FILE *f)
{
- fputs(_("Use the location as discovered by the Corelocation provider.\n"), f);
- fputs("\n", f);
+ fputs(_("Use the location as discovered by the Corelocation provider.\n"), f);
+ fputs("\n", f);
}
static int
location_corelocation_set_option(
struct location_state *state, const char *key, const char *value)
{
- fprintf(stderr, _("Unknown method parameter: `%s'.\n"), key);
- return -1;
+ weprintf(_("Unknown method parameter: `%s'."), key);
+ return -1;
}
static int
location_corelocation_get_fd(struct location_state *state)
{
- return state->pipe_fd_read;
+ return state->pipe_fd_read;
}
static int
-location_corelocation_handle(
- struct location_state *state,
- location_t *location, int *available)
+location_corelocation_handle(struct location_state *state, location_t *location, int *available)
{
- pipeutils_handle_signal(state->pipe_fd_read);
-
- [state->lock lock];
-
- int error = state->error;
- *location->lat = state->location;
- *available = state->available;
+ int error;
- [state->lock unlock];
+ pipeutils_handle_signal(state->pipe_fd_read);
- if (error) return -1;
+ [state->lock lock];
+ error = state->error;
+ *location->lat = state->location;
+ *available = state->available;
+ [state->lock unlock];
- return 0;
+ return error ? -1 : 0;
}
const location_provider_t corelocation_location_provider = {
- "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_fd_func *)location_corelocation_get_fd,
- (location_provider_handle_func *)location_corelocation_handle
+ "corelocation",
+ &location_corelocation_init,
+ &location_corelocation_start,
+ &location_corelocation_free,
+ &location_corelocation_print_help,
+ &location_corelocation_set_option,
+ &location_corelocation_get_fd,
+ &location_corelocation_handle
};