Skip to content

Instantly share code, notes, and snippets.

@tompng
Last active April 9, 2020 19:29
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tompng/6055496 to your computer and use it in GitHub Desktop.
Save tompng/6055496 to your computer and use it in GitHub Desktop.
ls2sl for mac
//g++ -framework ApplicationServices ls2sl.cc
//enable [System Preferences -> Universal Access -> Access for assistive devices]
#include <stdio.h>
#include <ApplicationServices/ApplicationServices.h>
#include <sys/time.h>
#define BUFSIZE 100
int keyBuffer[BUFSIZE];
struct timeval timeBuffer[BUFSIZE];
int bufferIndex=0;
void push(int key){
int i=bufferIndex%BUFSIZE;
bufferIndex++;
keyBuffer[i]=key;
gettimeofday(timeBuffer+i,NULL);
}
int get(int i){
if(i>=bufferIndex||i>=BUFSIZE)return -1;
return keyBuffer[(bufferIndex-i-1)%BUFSIZE];
}
double getTime(int i){
if(i>=bufferIndex||i>=BUFSIZE)return 1.0E+512;
struct timeval time;
gettimeofday(&time,NULL);
int index=(bufferIndex-i-1)%BUFSIZE;
return time.tv_sec-timeBuffer[index].tv_sec-(time.tv_usec-timeBuffer[index].tv_usec)/1000000.0;
}
CGEventRef keyFilter(CGEventTapProxy proxy,CGEventType type,CGEventRef event,void *refcon){
CGEventFlags flags=CGEventGetFlags(event);
//printf("flag=%d\n",(int)flags);
if(type==kCGEventFlagsChanged){
push(-1);
}else if(type==kCGEventKeyDown){
int key=CGEventGetIntegerValueField(event,kCGKeyboardEventKeycode);
if(flags==256)push(key);
else push(-1);
//printf("%d %d %d\n",get(2),get(1),get(0));
if(get(2)==37&&get(1)==1&&get(0)==36&&(getTime(3)-getTime(2)>0.4||get(3)==36)&&getTime(2)-getTime(1)<0.2&&getTime(1)<2){
CGEventTapPostEvent(proxy,CGEventCreateKeyboardEvent(NULL,51,true));
CGEventTapPostEvent(proxy,CGEventCreateKeyboardEvent(NULL,51,false));
CGEventTapPostEvent(proxy,CGEventCreateKeyboardEvent(NULL,51,true));
CGEventTapPostEvent(proxy,CGEventCreateKeyboardEvent(NULL,51,false));
CGEventTapPostEvent(proxy,CGEventCreateKeyboardEvent(NULL,1,true));
CGEventTapPostEvent(proxy,CGEventCreateKeyboardEvent(NULL,1,false));
CGEventTapPostEvent(proxy,CGEventCreateKeyboardEvent(NULL,37,true));
CGEventTapPostEvent(proxy,CGEventCreateKeyboardEvent(NULL,37,false));
CGEventTapPostEvent(proxy,CGEventCreateKeyboardEvent(NULL,36,true));
return NULL;
}
}
return event;
}
int main(){
int mask=0;
mask|=CGEventMaskBit(kCGEventFlagsChanged);
mask|=CGEventMaskBit(kCGEventKeyUp);
mask|=CGEventMaskBit(kCGEventKeyDown);
CFMachPortRef eventTap=CGEventTapCreate(kCGHIDEventTap,kCGHeadInsertEventTap,kCGEventTapOptionDefault,mask,keyFilter,NULL);
CFRunLoopSourceRef runLoopSourceRef=CFMachPortCreateRunLoopSource(NULL,eventTap,0);
CFRunLoopAddSource(CFRunLoopGetCurrent(),runLoopSourceRef,kCFRunLoopDefaultMode);
CFRunLoopRun();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment