Subversion Repositories Mobile Apps.GyroMouse

Rev

Rev 5 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 1
//
2
//  MouseHandler.swift
3
//  GyroServer
4
//
5
//  Created by Matteo Riva on 07/08/15.
6
//  Copyright © 2015 Matteo Riva. All rights reserved.
7
//
8
 
9
import CoreGraphics
10
import Cocoa
11
import Carbon
12
import CoreServices
13
 
14
class MouseHandler: NSObject, ServerHandlerDelegate {
15
 
16
    private let server = ServerHandler()
17
 
18
    private var activeScreen: Int {
19
        get {
20
            return UserDefaults.standard.integer(forKey: "activeScreen")
21
        }
22
    }
23
    private var mLoc: (x: CGFloat, y: CGFloat) = (x: 0, y: 0)
24
    private var isDragging = false
25
 
26
    override init() {
27
        super.init()
28
        resetPointerPosition(moveMouse: false)
29
        server.startBroadcast()
30
        NotificationCenter.default.addObserver(forName: ActiveScreenDidChangeNotification, object: nil, queue: OperationQueue.main) {[unowned self] (_) -> Void in
31
            self.resetPointerPosition(moveMouse: false)
32
        }
33
        NotificationCenter.default.addObserver(forName: ServerDidConnectNotification, object: nil, queue: OperationQueue.main) {[unowned self] (_) -> Void in
34
            self.resetPointerPosition(moveMouse: true)
35
            self.server.delegate = self
36
        }
37
        NotificationCenter.default.addObserver(forName: ServerDidDisconnectNotification, object: nil, queue: OperationQueue.main) {[unowned self] (_) -> Void in
38
            self.server.delegate = nil
39
            self.resetPointerPosition(moveMouse: false)
40
        }
41
    }
42
 
43
    deinit {
44
        NotificationCenter.default.removeObserver(self)
45
    }
46
 
47
    //MARK: - Mouse movements
7 pmbaty 48
 
49
    var averagedPoints: [CGPoint] = [ CGPoint(x: -1, y: -1), CGPoint(x: -1, y: -1), CGPoint(x: -1, y: -1), CGPoint(x: -1, y: -1), CGPoint(x: -1, y: -1), CGPoint(x: -1, y: -1) ]
1 pmbaty 50
 
7 pmbaty 51
    func computePointerMovement(grav: (X: Double, Y: Double, Z: Double), rotat: (X: Double, Z: Double), acc: (X: Double, Y: Double, Z: Double), moveVelocity: Double) {
1 pmbaty 52
        let frame = NSScreen.screens[activeScreen].frame
7 pmbaty 53
        let bounds = (origin: frame.origin, width: frame.maxX - 1, height: frame.maxY - 1)
1 pmbaty 54
 
7 pmbaty 55
        // compute new mouse location
56
        mLoc = (
57
            x: max(bounds.origin.x, min(mLoc.x + CGFloat((rotat.Z * -1) * (1 + abs(acc.Z)) * moveVelocity * abs(grav.Z)), bounds.width)),
58
            y: max(0,               min(mLoc.y + CGFloat((rotat.X * -1) * (1 + abs(acc.X)) * moveVelocity * abs(grav.Z)), bounds.height))
59
        )
1 pmbaty 60
 
7 pmbaty 61
        // initialize history array
62
        for i in 0...(averagedPoints.count - 1) {
63
            if ((averagedPoints[i].x == -1) && (averagedPoints[i].y == -1)) {
64
                averagedPoints[0].x = mLoc.x
65
                averagedPoints[0].y = mLoc.y
66
            }
67
        }
68
 
69
        // shift history array and insert new position at the end
70
        for i in 0...(averagedPoints.count - 2) {
71
            averagedPoints[i].x = averagedPoints[i + 1].x
72
            averagedPoints[i].y = averagedPoints[i + 1].y
73
        }
74
        averagedPoints[averagedPoints.count - 1].x = mLoc.x
75
        averagedPoints[averagedPoints.count - 1].y = mLoc.y
76
 
77
        // compute averaged coordinates
78
        var averagedPoint = CGPoint(x: 0, y: 0)
79
        for i in 0...(averagedPoints.count - 1) {
80
            averagedPoint.x += averagedPoints[i].x
81
            averagedPoint.y += averagedPoints[i].y
82
        }
83
        averagedPoint.x /= CGFloat(averagedPoints.count)
84
        averagedPoint.y /= CGFloat(averagedPoints.count)
85
 
86
        //print ("Updated mouse pos to \(averagedPoint.x),\(averagedPoint.y)")
87
 
88
        let mouseEvent = CGEvent(mouseEventSource: nil, mouseType: .mouseMoved, mouseCursorPosition: averagedPoint, mouseButton: .left)
1 pmbaty 89
        mouseEvent?.post(tap: CGEventTapLocation.cghidEventTap)
90
 
7 pmbaty 91
        if (isDragging) {
92
             let mouseEvent = CGEvent(mouseEventSource: nil, mouseType: .leftMouseDragged, mouseCursorPosition: averagedPoint, mouseButton: .left)
1 pmbaty 93
            mouseEvent?.post(tap: CGEventTapLocation.cghidEventTap)
94
        }
95
    }
96
 
97
    func resetPointerPosition(moveMouse: Bool) {
98
        let aIndex = UserDefaults.standard.integer(forKey: "activeScreen")
99
        let frame = NSScreen.screens[aIndex].frame
100
        let x = frame.midX
101
        let y = frame.midY - frame.origin.y
102
        NSLog("x: %f, y: %f, origin x: %f, y: %f, mid x: %f, y: %f", x,y,frame.origin.x, frame.origin.y, frame.midX, frame.midY)
103
        mLoc = (x: x, y: y)
104
        if moveMouse {
105
            let point = CGPoint(x: x, y: y)
106
            let mouseEvent = CGEvent(mouseEventSource: nil, mouseType: .mouseMoved, mouseCursorPosition: point, mouseButton: .left)
107
            mouseEvent?.post(tap: CGEventTapLocation.cghidEventTap)
108
        }
109
    }
110
 
111
    //MARK: - Mouse actions
112
 
113
    var rollGate = 0
114
 
7 pmbaty 115
    func scrollWithRoll(roll: Double, velocity: Double) {
1 pmbaty 116
        rollGate += 1
117
        if rollGate == 10 {
118
            let amount = (Int32) (roll * velocity * -50)
119
            let mouseEvent = CGEvent(scrollWheelEvent2Source: nil, units: .pixel, wheelCount: 1, wheel1: amount, wheel2: 0, wheel3: 0)
120
            mouseEvent?.post(tap: CGEventTapLocation.cghidEventTap)
121
 
122
            rollGate = 0
123
        }
124
    }
125
 
7 pmbaty 126
    func clickButton(isRightButton: Bool, isButtonDown: Bool) {
1 pmbaty 127
        let mousePos = CGPoint(x: mLoc.x, y: mLoc.y)
128
        let mouseEventType: CGEventType
129
        let mouseButton: CGMouseButton
130
 
7 pmbaty 131
        if (isRightButton) {
1 pmbaty 132
            mouseButton = .right
7 pmbaty 133
            mouseEventType = (isButtonDown ? .rightMouseDown : .rightMouseUp)
1 pmbaty 134
            isDragging = false
7 pmbaty 135
        } else {
136
            mouseButton = .left
137
            mouseEventType = (isButtonDown ? .leftMouseDown : .leftMouseUp)
138
            isDragging = isButtonDown
1 pmbaty 139
        }
140
 
141
        let mouseEvent = CGEvent(mouseEventSource: nil, mouseType: mouseEventType, mouseCursorPosition: mousePos, mouseButton: mouseButton)
142
        mouseEvent?.post(tap: CGEventTapLocation.cghidEventTap)
143
    }
144
 
145
    //MARK: - AppleScript launcher
146
 
7 pmbaty 147
    func runAppleScript(_ scriptText: String) {
1 pmbaty 148
        let script = NSAppleScript(source: scriptText)!
149
        var error: NSDictionary? = nil
150
        let resultMaybe = script.executeAndReturnError(&error) as NSAppleEventDescriptor?
5 pmbaty 151
        if (resultMaybe == nil)
1 pmbaty 152
        {
5 pmbaty 153
            let myStringDict = error as? [String:AnyObject]
154
            if (myStringDict?["NSAppleScriptErrorNumber"] as! Int16 == 1002) {
155
                let alert = NSAlert()
156
                alert.addButton(withTitle: "OK".localized)
157
                alert.messageText = "system_message".localized + "\n" + (myStringDict?["NSAppleScriptErrorBriefMessage"] as! String)
158
                alert.informativeText = "allow_perms".localized
159
                alert.alertStyle = .warning
160
                alert.runModal()
161
            }
1 pmbaty 162
            print (error as Any)
163
            return
164
        }
165
    }
166
}