Objective c 从带符号整数创建CGEvent

Objective c 从带符号整数创建CGEvent,objective-c,macos,cocoa,hotkeys,bitmask,Objective C,Macos,Cocoa,Hotkeys,Bitmask,在我继续之前,我想在这篇文章的开头说,这可能是最骇人听闻、彻头彻尾的邪恶、令人讨厌的话题,所以我不希望答案包含任何“法律”代码 在尝试访问OS X Mountain Lion用来包含激活口述的热键组合的内部首选项文件时,我遇到了一些精心制作的带符号整数,其中包含System preferences.app中定义的键代码。问题是,我能想到的将它们放入cgfevent的唯一方法是遍历并基本上解析出给定密钥代码的位掩码,这可能是徒劳和烦人的。而且因为CGEvent被方便地定义为一个内部结构(\uu C

在我继续之前,我想在这篇文章的开头说,这可能是最骇人听闻、彻头彻尾的邪恶、令人讨厌的话题,所以我不希望答案包含任何“法律”代码

在尝试访问OS X Mountain Lion用来包含激活口述的热键组合的内部首选项文件时,我遇到了一些精心制作的带符号整数,其中包含System preferences.app中定义的键代码。问题是,我能想到的将它们放入
cgfevent
的唯一方法是遍历并基本上解析出给定密钥代码的位掩码,这可能是徒劳和烦人的。而且因为
CGEvent
被方便地定义为一个内部结构(
\uu CGEvent
),所以无法看到它的内部组织(换句话说,我无法
malloc()
我的出路)。到目前为止,我获得的信息显示在下面的代码中:

/***************************************UNSAFE*****************************************************/
//1048584, -1048585 - Two Left CMD presses; 1048576, -1048577 - Two CMD presses; 8388608, -8388609 - Two Fn presses; 1048592, -1048593 - Two Right CMD presses
- (void)forceDictation {

    NSString *path = [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject]stringByAppendingPathComponent:@"Preferences/com.apple.symbolichotkeys.plist"];
    NSDictionary *dictationPrefs = [NSDictionary dictionaryWithContentsOfFile:path];
    NSDictionary *dictationDict = dictationPrefs[@"AppleSymbolicHotKeys"];
    NSDictionary *keyvalueDict = dictationDict[@"164"];
    NSDictionary *valueDict = keyvalueDict[@"value"];
    NSArray *parameters = valueDict[@"parameters"];
    NSInteger firstCode = [[parameters objectAtIndex:0]longLongValue];
    NSInteger secondCode = [[parameters objectAtIndex:1]longLongValue];
}

熟悉HIToolbox中事件位掩码的任何人都可以看到这些关键代码表示形式有多么大的帮助,只要它们能够很容易地转换为事件,然后发射成蓝色。

让我们看看位模式(您会注意到,我已经改变了它们的排列顺序):

除了以下几点,我无法从中看出什么:

  • 假设正值是“真实”值(请参阅我的评论,了解我关于为什么有两个以及为什么所有四对都是互补的理论),密钥标识符至少向上20位(请注意,在我顺序中的第一对中,正值正好是
    2**20
    ),并且至少4位长(2×Fn是
    2**23
  • 如果设置受到限制,则最低五位中至少有两位指定哪个键(左键或右键)。左边似乎是第一个⌘, 而右是第二位。如果该部分为零,则任何已识别的键都将匹配,例如左键或右键⌘.
但我们实际上可能不需要解析位

在我的MacBook Air上,运行会提供以下输出:

有些数字看起来很熟悉,不是吗

  • 我什么时候按a键⌘ 键,修饰符状态更改为1048000范围内的某个值
  • 当我按下Fn键时,修改器状态变为8388864。你的电话号码是8388608
让我们看看NSEvent.h中的修改器掩码:

这意味着较低的16位取决于设备:它们可能因机器或键盘而异。换句话说,您的低16位可能与我的低16位不同

但是等等!还有更多

如果我们查看I/O工具包的iolEvent.h,我们会发现与NSEvent中的面具相似的面具,另外还有:

因此,
LCMDKEYMASK
0b1000
RCMDKEYMASK
0b10000
。这也与左派相匹配-⌘ 对-⌘ 找到的值:左边是
NX\u命令掩码| NX\u设备CmdKeyMask
,右边是
NX\u命令掩码| NX\u设备CmdKeyMask

由此,我可以得出以下结论:

  • 这些数字并不是全部事件
  • 在每对中,正值是一个修改器标志掩码,负值只是它的补码
  • 需要生成的事件是修改器更改事件(
    kCGEventFlagsChanged
    ),与键代码查找的事件相同(当您打开该复选框时),每个事件的修改器标志如上所示。(我不知道你是否真的可以通过生成这样的事件来触发听写,你自己也不知道。)
  • 位布局并不十分重要,但如果您真的想知道,上半部分(“设备独立”)标识打开了哪些修改器,下半部分(“设备相关”,可能仅出现在标志更改事件中)标识刚刚按下了哪些键来更改它们
  • 修改器按键的次数大概是硬编码的(如果不是,则在别处指定)

这并不是说它对任何事情都有帮助,而是在每对数字
a
b
a=~b
之间。粗略猜测,这可能是一个反篡改措施:可能有一个检查
a^b=~0
。我的,我的,这是一个多么好的答案。为什么,我认为这是值得悬赏的。再坚持72小时,伙计。
2 × ⌘:
 1048576: 00000000000100000000000000000000
-1048577: 11111111111011111111111111111111

2 × left-⌘:
 1048584: 00000000000100000000000000001000
-1048585: 11111111111011111111111111110111

2 × right-⌘:
 1048592: 00000000000100000000000000010000
-1048593: 11111111111011111111111111101111

2 × Fn:
 8388608: 00000000100000000000000000000000
-8388609: 11111111011111111111111111111111
Modifier Change
  Keys:       ⌘
  Key Code:   65535 / 0xffff
  Modifiers:  1048848 / 0x100110

Modifier Change
  Keys:       
  Key Code:   65535 / 0xffff
  Modifiers:  256 / 0x100

Modifier Change
  Keys:       ⌘
  Key Code:   65535 / 0xffff
  Modifiers:  1048840 / 0x100108

Modifier Change
  Keys:       
  Key Code:   65535 / 0xffff
  Modifiers:  256 / 0x100

Modifier Change
  Keys:       
  Key Code:   65535 / 0xffff
  Modifiers:  8388864 / 0x800100

Modifier Change
  Keys:       
  Key Code:   65535 / 0xffff
  Modifiers:  256 / 0x100
NSCommandKeyMask            = 1 << 20,
NSFunctionKeyMask           = 1 << 23,
NSDeviceIndependentModifierFlagsMask    = 0xffff0000UL
/* device-dependent (really?) */

#define   NX_DEVICELCTLKEYMASK    0x00000001
#define   NX_DEVICELSHIFTKEYMASK  0x00000002
#define   NX_DEVICERSHIFTKEYMASK  0x00000004
#define   NX_DEVICELCMDKEYMASK    0x00000008
#define   NX_DEVICERCMDKEYMASK    0x00000010
#define   NX_DEVICELALTKEYMASK    0x00000020
#define   NX_DEVICERALTKEYMASK    0x00000040
#define NX_DEVICERCTLKEYMASK  0x00002000