+static CFMessagePortRef ashikase_;
+static bool cursor_;
+
+static bool Ashikase(bool always) {
+ if (ashikase_ == NULL)
+ ashikase_ = CFMessagePortCreateRemote(kCFAllocatorDefault, CFSTR("jp.ashikase.mousesupport"));
+ return ashikase_ != NULL && (always || cursor_);
+}
+
+static CFDataRef cfTrue_;
+static CFDataRef cfFalse_;
+
+typedef struct {
+ float x, y;
+ int buttons;
+ BOOL absolute;
+} MouseEvent;
+
+static MouseEvent event_;
+static CFDataRef cfEvent_;
+
+typedef enum {
+ MouseMessageTypeEvent,
+ MouseMessageTypeSetEnabled
+} MouseMessageType;
+
+static void AshikaseSetEnabled(bool enabled, bool always) {
+ if (!Ashikase(always))
+ return;
+
+ CFMessagePortSendRequest(ashikase_, MouseMessageTypeSetEnabled, cursor_ ? cfTrue_ : cfFalse_, 0, 0, NULL, NULL);
+}
+
+static bool AshikaseSendEvent(float x, float y, int buttons = 0) {
+ if (!Ashikase(false))
+ return false;
+
+ event_.x = x;
+ event_.y = y;
+ event_.buttons = buttons;
+ event_.absolute = true;
+
+ CFMessagePortSendRequest(ashikase_, MouseMessageTypeEvent, cfEvent_, 0, 0, NULL, NULL);
+
+ return true;
+}
+