aboutsummaryrefslogtreecommitdiff
path: root/src/carbon.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/carbon.c')
-rw-r--r--src/carbon.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/carbon.c b/src/carbon.c
new file mode 100644
index 0000000..dcfc2d8
--- /dev/null
+++ b/src/carbon.c
@@ -0,0 +1,77 @@
+#include "carbon.h"
+
+#define internal static
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated"
+internal inline char *
+find_process_name_for_psn(ProcessSerialNumber *psn)
+{
+ CFStringRef process_name_ref;
+ if (CopyProcessName(psn, &process_name_ref) == noErr) {
+ char *process_name = copy_cfstring(process_name_ref);
+ for (char *s = process_name; *s; ++s) *s = tolower(*s);
+ CFRelease(process_name_ref);
+ return process_name;
+ }
+ return NULL;
+}
+
+inline char *
+find_process_name_for_pid(pid_t pid)
+{
+ ProcessSerialNumber psn;
+ GetProcessForPID(pid, &psn);
+ return find_process_name_for_psn(&psn);
+}
+
+internal inline char *
+find_active_process_name(void)
+{
+ ProcessSerialNumber psn;
+ GetFrontProcess(&psn);
+ return find_process_name_for_psn(&psn);
+}
+#pragma clang diagnostic pop
+
+internal OSStatus
+carbon_event_handler(EventHandlerCallRef ref, EventRef event, void *context)
+{
+ struct carbon_event *carbon = (struct carbon_event *) context;
+
+ ProcessSerialNumber psn;
+ if (GetEventParameter(event,
+ kEventParamProcessID,
+ typeProcessSerialNumber,
+ NULL,
+ sizeof(psn),
+ NULL,
+ &psn) != noErr) {
+ return -1;
+ }
+
+ if (carbon->process_name) {
+ free(carbon->process_name);
+ carbon->process_name = NULL;
+ }
+
+ carbon->process_name = find_process_name_for_psn(&psn);
+
+ return noErr;
+}
+
+bool carbon_event_init(struct carbon_event *carbon)
+{
+ carbon->target = GetApplicationEventTarget();
+ carbon->handler = NewEventHandlerUPP(carbon_event_handler);
+ carbon->type.eventClass = kEventClassApplication;
+ carbon->type.eventKind = kEventAppFrontSwitched;
+ carbon->process_name = find_active_process_name();
+
+ return InstallEventHandler(carbon->target,
+ carbon->handler,
+ 1,
+ &carbon->type,
+ carbon,
+ &carbon->handler_ref) == noErr;
+}