Deepin Linux Desktop, 截图工具剖析(四) python - Xlib gtk.keysyms

来源:互联网 发布:安卓php环境 编辑:程序博客网 时间:2024/06/05 07:49

Python -Xlib

关于Xlib,网上相关都介绍比较少,只能从库文件那里获取信息啦 http://python-xlib.sourceforge.net/?page=home

基本概念就是:程序和X server建立连接,之后进行通信,Event之类都是通过这个链接进行的。至于Pixmap, Graphic Context之类的,还需要进一步学习。


Sample:

#!/usr/bin/env pyhon# message.py --example program illustrating use message dialog#import pygtk#pygtk.require('2.0')import gtkfrom  collections import namedtuplefrom Xlib import X, display, Xutil, Xcursorfont(screenWidth, screenHeight) = gtk.gdk.get_default_root_window().get_size()disp = display.Display()rootWindow = disp.screen().rootWM_HINTS = disp.intern_atom("WM_HINTS", True)WM_STATE = disp.intern_atom("WM_STATE", True)WM_DESKTOP  = disp.intern_atom("_NET_WM_DESKTOP", True)def enumXlibWindow():    ''' enumerate child window of rootWindow'''    return rootWindow.query_tree().childrendef findWindowByProperty(xlibWindow, atom=WM_STATE):    ''' find Window by property '''    result = xlibWindow.query_tree().children    if not result:        return None    else:        for children in result:            status = children.get_property(atom, WM_HINTS, 0, 0)            if status:                child = children            else:                child = findWindowByProperty(children, atom)        return childdef convertCoord(x, y, width, height):    ''' cut out overlop the screen'''    xWidth = x + width    yHeight = y + height           if x < 0 and y > 0 and  y < yHeight < screenHeight:        return (0, y, width+x, height)        if x < 0 and yHeight > screenHeight:        return (0, y, width+x, height - (yHeight - screenHeight))        if xWidth > screenWidth and yHeight > screenHeight:        return (x, y, width - (xWidth - screenWidth), height - (yHeight - screenHeight))        if  x > 0 and x < xWidth < screenWidth and yHeight > screenHeight:        return (x, y, width, height - (yHeight - screenHeight))        if xWidth > screenWidth and y > 0 and y < yHeight < screenHeight:        return (x, y, width - (xWidth - screenWidth), height)        if x < 0 and y < 0:        return (0, 0, xWidth, yHeight)        if x > 0 and x < xWidth < screenWidth and y < 0:        return (x, 0, width, yHeight)        if x > 0 and xWidth > screenWidth and y < 0:        return (x, 0, width - (xWidth - screenWidth), yHeight)     return (x, y, width, height)def getClientWindow(target):    ''' Enumerate clientWindow '''    status = target.get_property(WM_STATE, WM_HINTS, 0, 0)    if status:        return target    client = findWindowByProperty(target)    if client:        return client    return targetdef filterWindow():    ''' without other window'''    windowList = []    for xlibWindow in enumXlibWindow():        if xlibWindow.get_property(WM_DESKTOP, WM_HINTS, 0, 0):            windowList.append(xlibWindow)        else:             if findWindowByProperty(xlibWindow, WM_DESKTOP):                 windowList.append(xlibWindow)    return windowListdef getWindowCoord(xlibWindow):    ''' covert xlibWindow's coord'''    clientWindow = getClientWindow(xlibWindow)    if xlibWindow != clientWindow:        x = xlibWindow.get_geometry().x + clientWindow.get_geometry().x        y = xlibWindow.get_geometry().y + clientWindow.get_geometry().y - 26        width =  clientWindow.get_geometry().width        height = clientWindow.get_geometry().height + 26    else:        x = xlibWindow.get_geometry().x        y = xlibWindow.get_geometry().y        width = xlibWindow.get_geometry().width        height = xlibWindow.get_geometry().height    return (x, y, width, height)def getScreenshotWindowInfo():    ''' return (x, y, width, height) '''    coordInfo = namedtuple('coord', 'x y width height')    screenshotWindowInfo = []    screenshotWindowInfo.append(coordInfo(0, 0, screenWidth, screenHeight))    for eachWindow in filterWindow():        (x, y, width, height) = getWindowCoord(eachWindow)        screenshotWindowInfo.append(coordInfo(*convertCoord(x, y, width, height)))    return screenshotWindowInfoif __name__ == "__main__":    #message = gtk.MessageDialog(type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_OK)    #message.set_markup("An example error popup")    #message.run()    print getScreenshotWindowInfo()


Xlib的一个小Sample:


#/usr/bin/env pythonimport sys, osimport Xlibfrom Xlib import X, display, Xutil#change path so we find Xlib#sys.path.insert(1, os.path.join(sys.path[0], '..'))#Application windowclass Window:    def __init__(self, display):        self.d = display                #Find which screen to open the window on        self.screen = self.d.screen()                #background pattern        bgsize = 20        bgpm = self.screen.root.create_pixmap(            bgsize,            bgsize,            self.screen.root_depth            )        bggc = self.screen.root.create_gc(            foreground = self.screen.black_pixel,            background = self.screen.black_pixel        )        bggc.change(foreground=self.screen.white_pixel)                bgpm.arc(bggc, -bgsize/2, 0, bgsize, bgsize, 0, 360*64)        bgpm.arc(bggc, bgsize/2, 0, bgsize, bgsize, 0, 360*64)        bgpm.arc(bggc, 0, -bgsize/2, bgsize, bgsize, 0, 360*64)        bgpm.arc(bggc, 0, bgsize/2, bgsize, bgsize, 0, 360*64)                #Actual window        self.window = self.screen.root.create_window(            100, 100, 400, 300, 0,            self.screen.root_depth,            X.InputOutput,            X.CopyFromParent,                        #special attribute values            background_pixmap = bgpm,            event_mask = (                    X.StructureNotifyMask |                    X.ButtonReleaseMask                    ),            colormap = X.CopyFromParent            )        #Set some WM info        self.WM_DELETE_WINDOW = self.d.intern_atom('WM_DELETE_WINDOW')        self.WM_PROTOCOLS = self.d.intern_atom('WM_PROTOCOLS')                self.window.set_wm_name('Xlib example: childwin.py')        self.window.set_wm_icon_name('childwin.py')        self.window.set_wm_class('childwin', 'XlibExample')                self.window.set_wm_protocols([self.WM_DELETE_WINDOW])        self.window.set_wm_hints(                flags = Xutil.StateHint,                initial_state = Xutil.NormalState            )                self.window.set_wm_normal_hints(            flags = (Xutil.PPosition | Xutil.PSize | Xutil.PMinSize),            min_width = 50,            min_height = 50        )                #Map the window, making it visible        self.window.map()                #Child window        (self.childWidth, self.childHeight) = (20, 20)        self.childWindow = self.window.create_window(            20, 20, self.childWidth, self.childHeight, 0,            self.screen.root_depth,            X.CopyFromParent,            X.CopyFromParent,            #special attribute values            background_pixel = self.screen.white_pixel,            colormap = X.CopyFromParent,            )        self.childWindow.map()            def main_loop(self):        current = None        while 1:                e = self.d.next_event()                                #Window has been destroyed , quit                if e.type == X.DestroyNotify:                    sys.exit(0)                elif e.type == X.ButtonRelease:                    if e.detail == 1:                        print "Moving child window."                        self.childWindow.configure(                            x=e.event_x-self.childWidth/2,                            y=e.event_y-self.childHeight/2                            )                        self.d.flush()                elif e.type == X.ClientMessage:                    if e.client_type == self.WM_PROTOCOLS:                        fmt, data = e.data                        if fmt == 32 and data[0] == self.WM_DELETE_WINDOW:                            sys.exit(0)if __name__ == "__main__":    Window(display.Display()).main_loop()

Python module  gtk.keysyms   http://www.pygtk.org/docs/pygtk/class-gdkkeymap.html


>A keymap is a mapping from a Keymap key to key values. You canthink of a Keymap key as a representation of a symbol printed on a physicalkeyboard key. That is, it >contains three pieces of information. First, itcontains the hardware keycode; this is an identifying number for a physicalkey. Second, it contains the level of the key. The >level indicates whichsymbol on the key will be used, in a vertical direction. So on a standard USkeyboard, the key with the number "1" on it also has the exclamation >point("!") character on it. The level indicates whether to use the "1" or the "!"symbol. The letter keys are considered to have a lowercase letter at level0, and an uppercase >letter at level 1, though only the uppercase letter isprinted. Third, the Keymap key contains a group; groups are not used onstandard US keyboards, but are used in many >other countries. On a keyboardwith groups, there can be 3 or 4 symbols printed on a single key. The groupindicates movement in a horizontal direction. Usually groups are >used fortwo different languages. In group 0, a key might have two Englishcharacters, and in group 1 it might have two Hebrew characters. The Hebrewcharacters will be >printed on the key next to the English characters.


定义回调函数,目的是当 Ctrl+S, Ctrl+Z, M+S, M+Z,  Escape, Return这些按键组合的结果。

 def registerKeyBinding(self, keyEventName, callback):        '''Register a keybinding'''        self.keyBindings[keyEventName] = callback


0 0
原创粉丝点击