def __init__(self): self.key_hook = lambda x: True self.mouse_button_hook = lambda x: True self.mouse_move_hook = lambda x: True self.screen_hook = lambda x: True self.screenSize = [NSScreen.mainScreen().frame().size.width, NSScreen.mainScreen().frame().size.height] self.screenRatio = self.screenSize[0]/self.screenSize[1] self.location_hook = lambda x: True self.geo = locationTracking.LocationTracking() self.geo.startTracking() self.geo.locationchange_hook = self.got_location_change self.delegate = None
def get_window_screen(window): pos = get_window_pos(window) screens = NSScreen.screens() for screen in screens: frame = screen.frame() if pos.x >= frame.origin.x and \ pos.y >= frame.origin.y and \ pos.x <= frame.origin.x + frame.size.width and \ pos.y <= frame.origin.y + frame.size.height: return screen # screen not found return NSScreen.mainScreen()
def click_handler(self, event): recording = preferences.getValueForPreference('recording') event_screenshots = preferences.getValueForPreference('eventScreenshots') if event_screenshots: self.sniffer.activity_tracker.take_screenshot() if recording: # check if the clipboard has updated self.sniffer.clr.get_clipboard_contents() # get data ready to write loc = NSEvent.mouseLocation() scr = NSScreen.screens() xmin = 0 ymin = 0 for s in scr: if s.frame().origin.x < xmin: xmin = s.frame().origin.x if s.frame().origin.y < ymin: ymin = s.frame().origin.y x = int(loc.x) - xmin y = int(loc.y) - ymin #get click type click_type = "Unknown" if event.type() == NSLeftMouseDown: click_type = "Left" elif event.type() == NSRightMouseDown: click_type = "Right" # write JSON object to clicklog file text = '{"time": '+ str(cfg.NOW()) + ' , "button": "' + click_type + '", "location": [' + str(x) + ',' + str(y) + ']}' utils_cocoa.write_to_file(text, cfg.CLICKLOG)
def move_handler(self, event): recording = preferences.getValueForPreference('recording') event_screenshots = preferences.getValueForPreference( 'eventScreenshots') if event_screenshots: self.sniffer.activity_tracker.take_screenshot() if recording: if event.type() == NSMouseMoved: loc = NSEvent.mouseLocation() # get all the image size information scr = NSScreen.screens() xmin = 0 ymin = 0 for s in scr: if s.frame().origin.x < xmin: xmin = s.frame().origin.x if s.frame().origin.y < ymin: ymin = s.frame().origin.y x = int(loc.x) - xmin y = int(loc.y) - ymin # write JSON object to movelog file text = '{"time": ' + str(cfg.NOW()) + ' , "location": [' + str( x) + ',' + str(y) + ']}' utils_cocoa.write_to_file(text, cfg.MOVELOG)
def _screenImageOptions(screen): ''' Process an instance of NSScreen, returning its options as a hash ''' workspace = NSWorkspace.sharedWorkspace() if screen == NSScreen.mainScreen(): is_main = True else: is_main = False screen_options = workspace.desktopImageOptionsForScreen_(screen) scaling_factor = screen_options.objectForKey_( NSWorkspaceDesktopImageScalingKey) # NSImageScaling : NSNumber allow_clipping = screen_options.objectForKey_( NSWorkspaceDesktopImageAllowClippingKey) # NSNumber fill_color = screen_options.objectForKey_( NSWorkspaceDesktopImageFillColorKey) # NSColor image_url = workspace.desktopImageURLForScreen_( screen).absoluteString() # NSURL options_dict = { 'main': is_main, 'scaling_factor': scaling_factor, 'image_url': image_url, 'allow_clipping': allow_clipping } if fill_color: options_dict['fill_color'] = { 'r': fill_color.redComponent(), 'g': fill_color.greenComponent(), 'b': fill_color.blueComponent() } return options_dict
def move_handler(self, event): recording = preferences.getValueForPreference('recording') event_screenshots = preferences.getValueForPreference('eventScreenshots') if event_screenshots: self.sniffer.activity_tracker.take_screenshot() if recording: if event.type() == NSMouseMoved: loc = NSEvent.mouseLocation() # get all the image size information scr = NSScreen.screens() xmin = 0 ymin = 0 for s in scr: if s.frame().origin.x < xmin: xmin = s.frame().origin.x if s.frame().origin.y < ymin: ymin = s.frame().origin.y x = int(loc.x) - xmin y = int(loc.y) - ymin # write JSON object to movelog file text = '{"time": '+ str(cfg.NOW()) + ' , "location": [' + str(x) + ',' + str(y) + ']}' utils_cocoa.write_to_file(text, cfg.MOVELOG)
def wallpaper(): ''' Get desktop wallpaper for every screen, including scaling options. CLI Example: .. code-block:: bash salt '*' desktop.wallpaper ''' log.info('Enumerating settings for each screen') screens = NSScreen.screens() log.info('Getting settings for %d screen(s)', len(screens)) screen_list = [_screenImageOptions(screen) for screen in screens] from pprint import pprint pprint(screen_list) return screen_list
def set_wallpaper(screen_index, path): ''' Set desktop wallpaper for screen at index CLI Example: .. code-block:: bash salt '*' desktop.set_wallpaper 0 '/Library/Desktop Pictures/Solid Colors/Solid Aqua Graphite.png' ''' workspace = NSWorkspace.sharedWorkspace() screens = NSScreen.screens() screen = screens[screen_index] file_url = NSURL.fileURLWithPath_isDirectory_(path, False) options = {} (status, error) = workspace.setDesktopImageURL_forScreen_options_error_(file_url, screen, options, None) return status
def set_wallpaper(screen_index, path): ''' Set desktop wallpaper for screen at index CLI Example: .. code-block:: bash salt '*' desktop.set_wallpaper 0 '/Library/Desktop Pictures/Solid Colors/Solid Aqua Graphite.png' ''' workspace = NSWorkspace.sharedWorkspace() screens = NSScreen.screens() screen = screens[screen_index] file_url = NSURL.fileURLWithPath_isDirectory_(path, False) options = {} (status, error) = workspace.setDesktopImageURL_forScreen_options_error_( file_url, screen, options, None) return status
def _screenImageOptions(screen): ''' Process an instance of NSScreen, returning its options as a hash ''' workspace = NSWorkspace.sharedWorkspace() if screen == NSScreen.mainScreen(): is_main = True else: is_main = False screen_options = workspace.desktopImageOptionsForScreen_(screen) scaling_factor = screen_options.objectForKey_(NSWorkspaceDesktopImageScalingKey) # NSImageScaling : NSNumber allow_clipping = screen_options.objectForKey_(NSWorkspaceDesktopImageAllowClippingKey) # NSNumber fill_color = screen_options.objectForKey_(NSWorkspaceDesktopImageFillColorKey) # NSColor image_url = workspace.desktopImageURLForScreen_(screen).absoluteString() # NSURL options_dict = {'main': is_main, 'scaling_factor': scaling_factor, 'image_url': image_url, 'allow_clipping': allow_clipping} if fill_color: options_dict['fill_color'] = {'r': fill_color.redComponent(), 'g': fill_color.greenComponent(), 'b': fill_color.blueComponent()} return options_dict
def click_handler(self, event): recording = preferences.getValueForPreference('recording') event_screenshots = preferences.getValueForPreference( 'eventScreenshots') if event_screenshots: self.sniffer.activity_tracker.take_screenshot() if recording: # check if the clipboard has updated self.sniffer.clr.get_clipboard_contents() # get data ready to write loc = NSEvent.mouseLocation() scr = NSScreen.screens() xmin = 0 ymin = 0 for s in scr: if s.frame().origin.x < xmin: xmin = s.frame().origin.x if s.frame().origin.y < ymin: ymin = s.frame().origin.y x = int(loc.x) - xmin y = int(loc.y) - ymin #get click type click_type = "Unknown" if event.type() == NSLeftMouseDown: click_type = "Left" elif event.type() == NSRightMouseDown: click_type = "Right" # write JSON object to clicklog file text = '{"time": ' + str(cfg.NOW( )) + ' , "button": "' + click_type + '", "location": [' + str( x) + ',' + str(y) + ']}' utils_cocoa.write_to_file(text, cfg.CLICKLOG)
def get_screens(self): return [CocoaScreen(self, nsscreen) for nsscreen in NSScreen.screens()]
def screenshot(self, path, region = None): #https://pythonhosted.org/pyobjc/examples/Quartz/Core%20Graphics/CGRotation/index.html try: # record how long it takes to take screenshot start = time.time() # Set to capture entire screen, including multiple monitors if region is None: region = CG.CGRectInfinite # Create CGImage, composite image of windows in region image = CG.CGWindowListCreateImage( region, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault ) scr = NSScreen.screens() xmin = 0 ymin = 0 for s in scr: if s.frame().origin.x < xmin: xmin = s.frame().origin.x if s.frame().origin.y < ymin: ymin = s.frame().origin.y nativeHeight = CGImageGetHeight(image)*1.0 nativeWidth = CGImageGetWidth(image)*1.0 nativeRatio = nativeWidth/nativeHeight prefHeight = NSUserDefaultsController.sharedUserDefaultsController().values().valueForKey_('imageSize') height = int(prefHeight/scr[0].frame().size.height*nativeHeight) width = int(nativeRatio * height) heightScaleFactor = height/nativeHeight widthScaleFactor = width/nativeWidth mouseLoc = NSEvent.mouseLocation() x = int(mouseLoc.x) y = int(mouseLoc.y) w = 16 h = 24 scale_x = int((x-xmin) * widthScaleFactor) scale_y = int((y-h+5-ymin) * heightScaleFactor) scale_w = w*widthScaleFactor scale_h = h*heightScaleFactor #Allocate image data and create context for drawing image imageData = LaunchServices.objc.allocateBuffer(int(4 * width * height)) bitmapContext = Quartz.CGBitmapContextCreate( imageData, # image data we just allocated... width, height, 8, # 8 bits per component 4 * width, # bytes per pixel times number of pixels wide Quartz.CGImageGetColorSpace(image), # use the same colorspace as the original image Quartz.kCGImageAlphaPremultipliedFirst # use premultiplied alpha ) #Draw image on context at new scale rect = CG.CGRectMake(0.0,0.0,width,height) Quartz.CGContextDrawImage(bitmapContext, rect, image) # Add Mouse cursor to the screenshot cursorPath = "../Resources/cursor.png" cursorPathStr = NSString.stringByExpandingTildeInPath(cursorPath) cursorURL = NSURL.fileURLWithPath_(cursorPathStr) # Create a CGImageSource object from 'url'. cursorImageSource = Quartz.CGImageSourceCreateWithURL(cursorURL, None) # Create a CGImage object from the first image in the file. Image # indexes are 0 based. cursorOverlay = Quartz.CGImageSourceCreateImageAtIndex(cursorImageSource, 0, None) Quartz.CGContextDrawImage(bitmapContext, CG.CGRectMake(scale_x, scale_y, scale_w, scale_h), cursorOverlay) #Recreate image from context imageOut = Quartz.CGBitmapContextCreateImage(bitmapContext) #Image properties dictionary dpi = 72 # FIXME: Should query this from somewhere, e.g for retina display properties = { Quartz.kCGImagePropertyDPIWidth: dpi, Quartz.kCGImagePropertyDPIHeight: dpi, Quartz.kCGImageDestinationLossyCompressionQuality: 0.6, } #Convert path to url for saving image pathWithCursor = path[0:-4] + "_" + str(x) + "_" + str(y) + '.jpg' pathStr = NSString.stringByExpandingTildeInPath(pathWithCursor) url = NSURL.fileURLWithPath_(pathStr) #Set image destination (where it will be saved) dest = Quartz.CGImageDestinationCreateWithURL( url, LaunchServices.kUTTypeJPEG, # file type 1, # 1 image in file None ) # Add the image to the destination, with certain properties Quartz.CGImageDestinationAddImage(dest, imageOut, properties) # finalize the CGImageDestination object. Quartz.CGImageDestinationFinalize(dest) #For testing how long it takes to take screenshot stop = time.time() print 'took ' + str(height) + 'px image in ' + str(stop-start)[:5] + ' seconds' except KeyboardInterrupt: print "Keyboard interrupt" AppHelper.stopEventLoop() except errno.ENOSPC: NSLog("No space left on storage device. Turning off Selfspy recording.") self.delegate.toggleLogging_(self) except: NSLog("couldn't save image")
def screenshot(self, path, region = None): #https://pythonhosted.org/pyobjc/examples/Quartz/Core%20Graphics/CGRotation/index.html try: # record how long it takes to take screenshot start = time.time() scr = NSScreen.screens() # Trying to capture mouse cursor # Quartz.CGDisplayShowCursor(Quartz.CGMainDisplayID()) # Quartz.CGAssociateMouseAndMouseCursorPosition(True) # Set to capture entire screen, including multiple monitors if region is None: region = CG.CGRectInfinite # Create CGImage, composite image of windows in region image = None image = CG.CGWindowListCreateImage( region, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault ) xmin = 0 ymin = 0 for s in scr: if s.frame().origin.x < xmin: xmin = s.frame().origin.x if s.frame().origin.y < ymin: ymin = s.frame().origin.y nativeHeight = CGImageGetHeight(image)*1.0 nativeWidth = CGImageGetWidth(image)*1.0 nativeRatio = nativeWidth/nativeHeight prefHeight = NSUserDefaultsController.sharedUserDefaultsController().values().valueForKey_('imageSize') height = int(prefHeight) #int(prefHeight/scr[0].frame().size.height*nativeHeight) width = int(nativeRatio * height) # Computes the scale factor between the user resolution and the native screen resolution resolutionScaleFactor = scr[0].frame().size.height / nativeHeight # Computes the scale factor between the image size in the preferences and the user resolution prefScaleFactor = height / scr[0].frame().size.height mouseLoc = NSEvent.mouseLocation() x = int(mouseLoc.x) y = int(mouseLoc.y) w = 16 h = 24 scale_x = int((x-xmin) * prefScaleFactor) scale_y = int((y-h+5-ymin) * prefScaleFactor) #int((y-h+5-ymin) * heightScaleFactor) scale_w = w*prefScaleFactor scale_h = h*prefScaleFactor #Allocate image data and create context for drawing image imageData = None imageData = LaunchServices.objc.allocateBuffer(int(100)) imageData = LaunchServices.objc.allocateBuffer(int(4 * width * height)) bitmapContext = None bitmapContext = Quartz.CGBitmapContextCreate( imageData, # image data we just allocated... width, height, 8, # 8 bits per component 4 * width, # bytes per pixel times number of pixels wide Quartz.CGImageGetColorSpace(image), # use the same colorspace as the original image Quartz.kCGImageAlphaPremultipliedFirst # use premultiplied alpha ) #Draw image on context at new scale rect = CG.CGRectMake(0.0,0.0,width,height) Quartz.CGContextDrawImage(bitmapContext, rect, image) # Add Mouse cursor to the screenshot cursorPath = "../Resources/cursor.png" cursorPathStr = NSString.stringByExpandingTildeInPath(cursorPath) cursorURL = NSURL.fileURLWithPath_(cursorPathStr) # Create a CGImageSource object from 'url'. cursorImageSource = None cursorImageSource = Quartz.CGImageSourceCreateWithURL(cursorURL, None) # Create a CGImage object from the first image in the file. Image # indexes are 0 based. cursorOverlay = None cursorOverlay = Quartz.CGImageSourceCreateImageAtIndex(cursorImageSource, 0, None) Quartz.CGContextDrawImage(bitmapContext, CG.CGRectMake(scale_x, scale_y, scale_w, scale_h), cursorOverlay) #Recreate image from context imageOut = Quartz.CGBitmapContextCreateImage(bitmapContext) #Image properties dictionary dpi = 72 # FIXME: Should query this from somewhere, e.g for retina display properties = { Quartz.kCGImagePropertyDPIWidth: dpi, Quartz.kCGImagePropertyDPIHeight: dpi, Quartz.kCGImageDestinationLossyCompressionQuality: 0.6, } # Getting id of current window and application try: activeAppName = self.workspace.activeApplication()['NSApplicationName'] except: activeAppName = "" print "failed NSApplicationName" active_app_id = self.getProcessIDFromName(activeAppName) options = kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements windowList = CGWindowListCopyWindowInfo(options, kCGNullWindowID) for window in windowList: # window_name = str(window.get('kCGWindowName', u'').encode('ascii', 'replace')) window_name = self.getWindowName(window) owner = window['kCGWindowOwnerName'] if (activeAppName == owner and window_name != ''): break active_window_id = self.getWindowIDFromName(window_name) # Done with getting id of current window and application #Convert path to url for saving image pathWithCursor = path[0:-4] + "_" + str(x) + "_" + str(y) if (active_app_id != None and active_app_id != '') : pathWithCursor = pathWithCursor + "_app" + str(active_app_id) if (active_window_id != None and active_window_id != '') : pathWithCursor = pathWithCursor + "_win" + str(active_window_id) pathWithCursor = pathWithCursor + '.jpg' # print pathWithCursor pathStr = NSString.stringByExpandingTildeInPath(pathWithCursor) url = NSURL.fileURLWithPath_(pathStr) #Set image destination (where it will be saved) dest = Quartz.CGImageDestinationCreateWithURL( url, LaunchServices.kUTTypeJPEG, # file type 1, # 1 image in file None ) # Add the image to the destination, with certain properties Quartz.CGImageDestinationAddImage(dest, imageOut, properties) # finalize the CGImageDestination object. Quartz.CGImageDestinationFinalize(dest) #For testing how long it takes to take screenshot stop = time.time() # print 'took ' + str(height) + 'px image in ' + str(stop-start)[:5] + ' seconds' except KeyboardInterrupt: print "Keyboard interrupt" AppHelper.stopEventLoop() except errno.ENOSPC: NSLog("No space left on storage device. Turning off Selfspy recording.") self.delegate.toggleLogging_(self) except: NSLog("couldn't save image")