def _get_device_interface(self, generic_device): plug_in_interface = \ ctypes.POINTER(ctypes.POINTER(IUnknown))() score = ctypes.c_int32() _oscheck( carbon.IOCreatePlugInInterfaceForService( generic_device, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, ctypes.byref(plug_in_interface), ctypes.byref(score)) ) carbon.CFUUIDGetUUIDBytes.restype = CFUUIDBytes hid_device_interface = \ ctypes.POINTER(ctypes.POINTER(IOHIDDeviceInterface))() _oscheck( plug_in_interface.contents.contents.QueryInterface( plug_in_interface, carbon.CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), ctypes.byref(hid_device_interface)) ) plug_in_interface.contents.contents.Release(plug_in_interface) return hid_device_interface
def add_font_data(cls, data): container = c_void_p() r = carbon.ATSFontActivateFromMemory(data, len(data), kATSFontContextLocal, kATSFontFormatUnspecified, None, 0, byref(container)) _oscheck(r)
def set_mode(self, mode): assert mode.screen is self if not self._initial_mode: self._initial_mode = self.get_mode() _oscheck(carbon.CGDisplayCapture(self.id)) _oscheck(carbon.CGDisplaySwitchToMode(self.id, mode.mode)) self.width = mode.width self.height = mode.height
def set_layout_attributes(layout, attributes): if attributes: # attributes is a dict of ATSUAttributeTag => ctypes value tags, values = zip(*attributes.items()) tags = (c_int * len(tags))(*tags) sizes = (c_uint * len(values))(*[sizeof(v) for v in values]) values = (c_void_p * len(values))(*[cast(pointer(v), c_void_p) \ for v in values]) r = carbon.ATSUSetLayoutControls(layout, len(tags), tags, sizes, values) _oscheck(r)
def get_matching_services(master_port, matching_dictionary): # Consumes reference to matching_dictionary iterator = io_iterator_t() _oscheck( carbon.IOServiceGetMatchingServices(master_port, matching_dictionary, ctypes.byref(iterator))) services = [] while carbon.IOIteratorIsValid(iterator): service = carbon.IOIteratorNext(iterator) if not service: break services.append(service) carbon.IOObjectRelease(iterator) return services
def get_matching_services(master_port, matching_dictionary): # Consumes reference to matching_dictionary iterator = io_iterator_t() _oscheck( carbon.IOServiceGetMatchingServices(master_port, matching_dictionary, ctypes.byref(iterator)) ) services = [] while carbon.IOIteratorIsValid(iterator): service = carbon.IOIteratorNext(iterator) if not service: break services.append(service) carbon.IOObjectRelease(iterator) return services
def _tablet_event(self, next_handler, ev, data): '''Process tablet event and return True if some event was processed. Return True if no tablet event found. ''' event_type = ctypes.c_uint32() r = carbon.GetEventParameter(ev, kEventParamTabletEventType, typeUInt32, None, ctypes.sizeof(event_type), None, ctypes.byref(event_type)) if r != noErr: return False if event_type.value == kEventTabletProximity: proximity_rec = TabletProximityRec() _oscheck( carbon.GetEventParameter(ev, kEventParamTabletProximityRec, typeTabletProximityRec, None, ctypes.sizeof(proximity_rec), None, ctypes.byref(proximity_rec)) ) cursor = self._get_cursor(proximity_rec) if proximity_rec.enterProximity: self.dispatch_event('on_enter', cursor) else: self.dispatch_event('on_leave', cursor) elif event_type.value == kEventTabletPoint: point_rec = TabletPointRec() _oscheck( carbon.GetEventParameter(ev, kEventParamTabletPointRec, typeTabletPointRec, None, ctypes.sizeof(point_rec), None, ctypes.byref(point_rec)) ) #x = point_rec.absX #y = point_rec.absY x, y = self.window._get_mouse_position(ev) pressure = point_rec.pressure / float(0xffff) #point_rec.tiltX, #point_rec.tiltY, #point_rec.rotation, #point_rec.tangentialPressure, self.dispatch_event('on_motion', self._cursor, x, y, pressure, 0., 0.) carbon.CallNextEventHandler(next_handler, ev) return noErr
def _layout_callback(self, operation, line, ref, extra, callback_status): if not line: return 0 records = c_void_p() n_records = c_uint() r = carbon.ATSUDirectGetLayoutDataArrayPtrFromLineRef( line, kATSUDirectDataLayoutRecordATSLayoutRecordVersion1, 0, byref(records), byref(n_records)) _oscheck(r) records = cast(records, POINTER(ATSLayoutRecord * n_records.value)).contents self._glyph_advance = fix2float(records[-1].realPos) callback_status.contents = kATSULayoutOperationCallbackStatusContinue return 0
def _tablet_event(self, next_handler, ev, data): '''Process tablet event and return True if some event was processed. Return True if no tablet event found. ''' event_type = ctypes.c_uint32() r = carbon.GetEventParameter(ev, kEventParamTabletEventType, typeUInt32, None, ctypes.sizeof(event_type), None, ctypes.byref(event_type)) if r != noErr: return False if event_type.value == kEventTabletProximity: proximity_rec = TabletProximityRec() _oscheck( carbon.GetEventParameter(ev, kEventParamTabletProximityRec, typeTabletProximityRec, None, ctypes.sizeof(proximity_rec), None, ctypes.byref(proximity_rec))) cursor = self._get_cursor(proximity_rec) if proximity_rec.enterProximity: self.dispatch_event('on_enter', cursor) else: self.dispatch_event('on_leave', cursor) elif event_type.value == kEventTabletPoint: point_rec = TabletPointRec() _oscheck( carbon.GetEventParameter(ev, kEventParamTabletPointRec, typeTabletPointRec, None, ctypes.sizeof(point_rec), None, ctypes.byref(point_rec))) #x = point_rec.absX #y = point_rec.absY x, y = self.window._get_mouse_position(ev) pressure = point_rec.pressure / float(0xffff) #point_rec.tiltX, #point_rec.tiltY, #point_rec.rotation, #point_rec.tangentialPressure, self.dispatch_event('on_motion', self._cursor, x, y, pressure, 0., 0.) carbon.CallNextEventHandler(next_handler, ev) return noErr
def _init_controls(self): elements_array = CFArrayRef() _oscheck( self._device.contents.contents.copyMatchingElements( self._device, None, ctypes.byref(elements_array))) self._control_cookies = {} controls = [] n_elements = carbon.CFArrayGetCount(elements_array) for i in range(n_elements): properties = carbon.CFArrayGetValueAtIndex(elements_array, i) control = _create_control(properties) if control: controls.append(control) self._control_cookies[control._cookie] = control carbon.CFRelease(elements_array) return controls
def _layout_callback(self, operation, line, ref, extra, callback_status): if not line: return 0 records = c_void_p() n_records = c_uint() r = carbon.ATSUDirectGetLayoutDataArrayPtrFromLineRef(line, kATSUDirectDataLayoutRecordATSLayoutRecordVersion1, 0, byref(records), byref(n_records)) _oscheck(r) records = cast(records, POINTER(ATSLayoutRecord * n_records.value)).contents self._glyph_advance = fix2float(records[-1].realPos) callback_status.contents = kATSULayoutOperationCallbackStatusContinue return 0
def _init_controls(self): elements_array = CFArrayRef() _oscheck( self._device.contents.contents.copyMatchingElements(self._device, None, ctypes.byref(elements_array)) ) self._control_cookies = {} controls = [] n_elements = carbon.CFArrayGetCount(elements_array) for i in range(n_elements): properties = carbon.CFArrayGetValueAtIndex(elements_array, i) control = _create_control(properties) if control: controls.append(control) self._control_cookies[control._cookie] = control carbon.CFRelease(elements_array) return controls
def open(self, window=None, exclusive=False): super(DarwinHIDDevice, self).open(window, exclusive) flags = 0 if exclusive: flags |= kIOHIDOptionsTypeSeizeDevice result = self._device.contents.contents.open(self._device, flags) if result == 0: self._open = True elif result == kIOReturnExclusiveAccess: raise DeviceExclusiveException() # Create event queue self._queue = self._device.contents.contents.allocQueue(self._device) _oscheck( self._queue.contents.contents.create(self._queue, 0, self._queue_depth) ) # Add all controls into queue for control in self._controls: r = self._queue.contents.contents.addElement(self._queue, control._cookie, 0) if r != 0: print 'error adding %r' % control self._event_source = CFRunLoopSourceRef() self._queue_callback_func = IOHIDCallbackFunction(self._queue_callback) _oscheck( self._queue.contents.contents.createAsyncEventSource(self._queue, ctypes.byref(self._event_source)) ) _oscheck( self._queue.contents.contents.setEventCallout(self._queue, self._queue_callback_func, None, None) ) event_loop = fos.lib.pyglet.app.platform_event_loop._event_loop carbon.GetCFRunLoopFromEventLoop.restype = void_p run_loop = carbon.GetCFRunLoopFromEventLoop(event_loop) kCFRunLoopDefaultMode = \ CFStringRef.in_dll(carbon, 'kCFRunLoopDefaultMode') carbon.CFRunLoopAddSource(run_loop, self._event_source, kCFRunLoopDefaultMode) _oscheck( self._queue.contents.contents.start(self._queue) )
def _get_device_interface(self, generic_device): plug_in_interface = \ ctypes.POINTER(ctypes.POINTER(IUnknown))() score = ctypes.c_int32() _oscheck( carbon.IOCreatePlugInInterfaceForService( generic_device, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, ctypes.byref(plug_in_interface), ctypes.byref(score))) carbon.CFUUIDGetUUIDBytes.restype = CFUUIDBytes hid_device_interface = \ ctypes.POINTER(ctypes.POINTER(IOHIDDeviceInterface))() _oscheck( plug_in_interface.contents.contents.QueryInterface( plug_in_interface, carbon.CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), ctypes.byref(hid_device_interface))) plug_in_interface.contents.contents.Release(plug_in_interface) return hid_device_interface
def __init__(self, display, generic_device): super(DarwinHIDDevice, self).__init__(display, name=None) self._device = self._get_device_interface(generic_device) properties = CFMutableDictionaryRef() _oscheck( carbon.IORegistryEntryCreateCFProperties(generic_device, ctypes.byref(properties), None, 0)) self.name = get_property(properties, "Product") self.manufacturer = get_property(properties, "Manufacturer") self.usage_page = get_property(properties, 'PrimaryUsagePage') self.usage = get_property(properties, 'PrimaryUsage') carbon.CFRelease(properties) self._controls = self._init_controls() self._open = False self._queue = None self._queue_depth = 8 # Number of events queue can buffer
def __init__(self, display, generic_device): super(DarwinHIDDevice, self).__init__(display, name=None) self._device = self._get_device_interface(generic_device) properties = CFMutableDictionaryRef() _oscheck( carbon.IORegistryEntryCreateCFProperties(generic_device, ctypes.byref(properties), None, 0) ) self.name = get_property(properties, "Product") self.manufacturer = get_property(properties, "Manufacturer") self.usage_page = get_property(properties, 'PrimaryUsagePage') self.usage = get_property(properties, 'PrimaryUsage') carbon.CFRelease(properties) self._controls = self._init_controls() self._open = False self._queue = None self._queue_depth = 8 # Number of events queue can buffer
def open(self, window=None, exclusive=False): super(DarwinHIDDevice, self).open(window, exclusive) flags = 0 if exclusive: flags |= kIOHIDOptionsTypeSeizeDevice result = self._device.contents.contents.open(self._device, flags) if result == 0: self._open = True elif result == kIOReturnExclusiveAccess: raise DeviceExclusiveException() # Create event queue self._queue = self._device.contents.contents.allocQueue(self._device) _oscheck( self._queue.contents.contents.create(self._queue, 0, self._queue_depth)) # Add all controls into queue for control in self._controls: r = self._queue.contents.contents.addElement( self._queue, control._cookie, 0) if r != 0: print 'error adding %r' % control self._event_source = CFRunLoopSourceRef() self._queue_callback_func = IOHIDCallbackFunction(self._queue_callback) _oscheck( self._queue.contents.contents.createAsyncEventSource( self._queue, ctypes.byref(self._event_source))) _oscheck( self._queue.contents.contents.setEventCallout( self._queue, self._queue_callback_func, None, None)) event_loop = fos.lib.pyglet.app.platform_event_loop._event_loop carbon.GetCFRunLoopFromEventLoop.restype = void_p run_loop = carbon.GetCFRunLoopFromEventLoop(event_loop) kCFRunLoopDefaultMode = \ CFStringRef.in_dll(carbon, 'kCFRunLoopDefaultMode') carbon.CFRunLoopAddSource(run_loop, self._event_source, kCFRunLoopDefaultMode) _oscheck(self._queue.contents.contents.start(self._queue))
def close(self): super(DarwinHIDDevice, self).close() if not self._open: return _oscheck(self._queue.contents.contents.stop(self._queue)) _oscheck(self._queue.contents.contents.dispose(self._queue)) self._queue.contents.contents.Release(self._queue) self._queue = None _oscheck(self._device.contents.contents.close(self._device)) self._open = False
def close(self): super(DarwinHIDDevice, self).close() if not self._open: return _oscheck( self._queue.contents.contents.stop(self._queue) ) _oscheck( self._queue.contents.contents.dispose(self._queue) ) self._queue.contents.contents.Release(self._queue) self._queue = None _oscheck( self._device.contents.contents.close(self._device) ) self._open = False
def get_gdevice(self): gdevice = POINTER(None)() _oscheck(carbon.DMGetGDeviceByDisplayID(self.id, byref(gdevice), False)) return gdevice
def restore_mode(self): if self._initial_mode: _oscheck(carbon.CGDisplaySwitchToMode(self.id, self._initial_mode.mode)) _oscheck(carbon.CGDisplayRelease(self.id))
def get_master_port(): master_port = mach_port_t() _oscheck( carbon.IOMasterPort(MACH_PORT_NULL, ctypes.byref(master_port)) ) return master_port
def get_master_port(): master_port = mach_port_t() _oscheck(carbon.IOMasterPort(MACH_PORT_NULL, ctypes.byref(master_port))) return master_port
def _create(self): if self._window: # The window is about to be recreated; destroy everything # associated with the old window, then the window itself. self._remove_track_region() self._remove_event_handlers() self.context.detach() self.canvas = None carbon.DisposeWindow(self._window) self._window = None self._window = WindowRef() if self._fullscreen: rect = Rect() rect.left = 0 rect.top = 0 rect.right = self.screen.width rect.bottom = self.screen.height r = carbon.CreateNewWindow(kSimpleWindowClass, kWindowNoAttributes, byref(rect), byref(self._window)) _oscheck(r) # Set window level to shield level level = carbon.CGShieldingWindowLevel() WindowGroupRef = c_void_p group = WindowGroupRef() _oscheck(carbon.CreateWindowGroup(0, byref(group))) _oscheck(carbon.SetWindowGroup(self._window, group)) _oscheck(carbon.SetWindowGroupLevel(group, level)) # Set black background color = RGBColor(0, 0, 0) _oscheck(carbon.SetWindowContentColor(self._window, byref(color))) self._mouse_in_window = True self.dispatch_event("on_resize", self._width, self._height) self.dispatch_event("on_show") self.dispatch_event("on_expose") self._view_x = (self.screen.width - self._width) // 2 self._view_y = (self.screen.height - self._height) // 2 self.canvas = CarbonCanvas(self.display, self.screen, carbon.GetWindowPort(self._window)) self.canvas.bounds = (self._view_x, self._view_y, self._width, self._height) else: # Create floating window rect = Rect() location = None # TODO if location is not None: rect.left = location[0] rect.top = location[1] else: rect.top = rect.left = 0 rect.right = rect.left + self._width rect.bottom = rect.top + self._height styles = { self.WINDOW_STYLE_DEFAULT: ( kDocumentWindowClass, kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute, ), self.WINDOW_STYLE_DIALOG: (kDocumentWindowClass, kWindowCloseBoxAttribute), self.WINDOW_STYLE_TOOL: (kUtilityWindowClass, kWindowCloseBoxAttribute), self.WINDOW_STYLE_BORDERLESS: (kSimpleWindowClass, kWindowNoAttributes), } window_class, window_attributes = styles.get(self._style, kDocumentWindowClass) if self._resizable: window_attributes |= kWindowFullZoomAttribute | kWindowLiveResizeAttribute | kWindowResizableAttribute r = carbon.CreateNewWindow(window_class, window_attributes, byref(rect), byref(self._window)) _oscheck(r) if location is None: carbon.RepositionWindow(self._window, c_void_p(), kWindowCascadeOnMainScreen) self.canvas = CarbonCanvas(self.display, self.screen, carbon.GetWindowPort(self._window)) self._view_x = self._view_y = 0 self.context.attach(self.canvas) self.set_caption(self._caption) # Get initial state self._event_dispatcher = carbon.GetEventDispatcherTarget() self._current_modifiers = carbon.GetCurrentKeyModifiers().value self._mapped_modifiers = self._map_modifiers(self._current_modifiers) # (re)install Carbon event handlers self._install_event_handlers() self._create_track_region() self.switch_to() # XXX self.set_vsync(self._vsync) if self._visible: self.set_visible(True)
def _create(self): if self._window: # The window is about to be recreated; destroy everything # associated with the old window, then the window itself. self._remove_track_region() self._remove_event_handlers() self.context.detach() self.canvas = None carbon.DisposeWindow(self._window) self._window = None self._window = WindowRef() if self._fullscreen: rect = Rect() rect.left = 0 rect.top = 0 rect.right = self.screen.width rect.bottom = self.screen.height r = carbon.CreateNewWindow(kSimpleWindowClass, kWindowNoAttributes, byref(rect), byref(self._window)) _oscheck(r) # Set window level to shield level level = carbon.CGShieldingWindowLevel() WindowGroupRef = c_void_p group = WindowGroupRef() _oscheck(carbon.CreateWindowGroup(0, byref(group))) _oscheck(carbon.SetWindowGroup(self._window, group)) _oscheck(carbon.SetWindowGroupLevel(group, level)) # Set black background color = RGBColor(0, 0, 0) _oscheck(carbon.SetWindowContentColor(self._window, byref(color))) self._mouse_in_window = True self.dispatch_event('on_resize', self._width, self._height) self.dispatch_event('on_show') self.dispatch_event('on_expose') self._view_x = (self.screen.width - self._width) // 2 self._view_y = (self.screen.height - self._height) // 2 self.canvas = CarbonCanvas(self.display, self.screen, carbon.GetWindowPort(self._window)) self.canvas.bounds = (self._view_x, self._view_y, self._width, self._height) else: # Create floating window rect = Rect() location = None # TODO if location is not None: rect.left = location[0] rect.top = location[1] else: rect.top = rect.left = 0 rect.right = rect.left + self._width rect.bottom = rect.top + self._height styles = { self.WINDOW_STYLE_DEFAULT: (kDocumentWindowClass, kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute), self.WINDOW_STYLE_DIALOG: (kDocumentWindowClass, kWindowCloseBoxAttribute), self.WINDOW_STYLE_TOOL: (kUtilityWindowClass, kWindowCloseBoxAttribute), self.WINDOW_STYLE_BORDERLESS: (kSimpleWindowClass, kWindowNoAttributes) } window_class, window_attributes = \ styles.get(self._style, kDocumentWindowClass) if self._resizable: window_attributes |= (kWindowFullZoomAttribute | kWindowLiveResizeAttribute | kWindowResizableAttribute) r = carbon.CreateNewWindow(window_class, window_attributes, byref(rect), byref(self._window)) _oscheck(r) if location is None: carbon.RepositionWindow(self._window, c_void_p(), kWindowCascadeOnMainScreen) self.canvas = CarbonCanvas(self.display, self.screen, carbon.GetWindowPort(self._window)) self._view_x = self._view_y = 0 self.context.attach(self.canvas) self.set_caption(self._caption) # Get initial state self._event_dispatcher = carbon.GetEventDispatcherTarget() self._current_modifiers = carbon.GetCurrentKeyModifiers().value self._mapped_modifiers = self._map_modifiers(self._current_modifiers) # (re)install Carbon event handlers self._install_event_handlers() self._create_track_region() self.switch_to() # XXX self.set_vsync(self._vsync) if self._visible: self.set_visible(True)