加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

[转载]Xlib 窗口属性(2)

(2016-03-01 18:49:37)
标签:

转载

分类: Linux
原文地址:Xlib 窗口属性(2)作者:枯草
事件队列管理
 
      Xlib 维护一个事件队列。不过,操作系统也可能在其还没有读入事件队列的网络连接中缓冲数据。
 
      要检查事件队列中的事件数目,使用 XEventsQueued。
 
      int XEventsQueued(display, mode )
            Display *display ;
            int mode ;
      display   指定到 X server 的连接。
      mode    指定模式。你可以发送 QueuedAlready、QueuedAfterFlush、或者 QueuedAfterReadiing。
 
      如果模式是 QueuedAlready,XEventsQueued 返回已经在事件队列中的事件数目(并且从不执行系统调用)。如果模式是 QueuedAfterFlush,如果已经在事件队列中的事件数目不是零的话,XEventsQueued 返回它。如果没有事件在队列中,XEventsQueued 刷新输出缓冲区,尝试将更多的事件从应用程序的连接中读出,并且返回读取的数目。如果 mode 是 QueuedAfterReading,并且如果已经在队列中的事件数目不是零,XEventsQueued 返回它。如果队列中没有事件,XEventsQueued 尝试从应用程序的连接中读出更多的事件但并不刷新输出缓冲区,并且返回读出的数目。
 
      如果队列中已有事件,XEventsQueued 总是立即返回而无须任何 I/O。模式为 QueuedAfterFlush 的 XEventsQueued 在行为上与 XPending 是一致的。模式为 QueuedAlready 的 XEventsQueued 与 XQLength 函数一致。
 
      用 XPending 返回未决的事件数目,
      int XPending(display )
        Display *display ;
      display   指定到 X server 的连接。
 
      XPending 函数返回已经从 X server 接收到但还没有从队列中移出的事件数目。XPending 与模式指定为 QueuedAfterFlush 的 XEventsQueued 一致。
 
维护事件队列
 
      Xlib 提供用于维护事件队列的函数。包括三部分:
•获取事件,随后将它们从队列中移出
•在队列中窥探事件而不用将它们移出
•获取与事件掩码或者你提供的任意断言过程匹配的事件
1. 返回下一个事件
 
      要得到下一个事件并将其从队列中移出,使用 XNextEvent。
      XNextEvent(display, event_return )
        Display *display ;
        XEvent *event_return ;
      display   指定到 X server 的连接。
      event_return   返回队列中的下一个事件。
      XNextEvent 函数从事件队列拷贝第一个事件到指定的 XEvent 结构中,然后将这个事件从队列中移出。如果事件队列是空的,XNextEvent 刷新输出缓冲区并阻塞直到收到事件。
 
      使用 XPeekEvent 来窥探事件队列。
      XPeekEvent(display, event_return )
        Display *display ;
        XEvent *event_return ;
      display   指定到 X server 的连接。
      event_return   返回与相关结构匹配事件的一个副本。
      XPeekEvent 函数从队列中返回第一个事件,但是它并不将事件从队列中移出。如果队列为空,XPeekEvent 刷新输出缓冲区并阻塞直到接收到事件。它随后将事件复制到客户程序补充的 XEvent 结构中,而不将事件从事件队列中移出。
 
2. 使用断言过程选择事件
 
      在这一部分中讨论的每一个函数都要求你传送一个断言过程来判断某个事件是否与你想要的相匹配。你的断言过程必须决定事件是否有用,并且绝不能调用 Xlib 函数。特别是,断言过程是从事件程序内部调用的,这个事件程序必须锁定数据结构以使事件队列在多线程环境中是一致的。
 
      断言过程以及其相关的参数是:
      Bool (*predicate)(display, event, arg )
        Display *display ;
        XEvent *event ;
        char *arg ;
      display  指定到 X server 的连接。
      event  指定 XEvent 结构。
      arg  指定从 XIfEvent、XCheckIfEvent、或者 XPeekIfEvent 函数中传送入的参数。
      队列中的每一个事件都调用断言过程一次,直到它找到一个匹配的事件。找到匹配的以后,断言过程必须返回 True。如果它不能找到匹配的,必须返回 False。
 
      为了匹配事件,要检查事件队列,并且如果找到,用 XIfEvent 将事件从队列中移出。
      XIfEvent(display, event_return, predicate, arg )
        Display *display ;
        XEvent *event_return ;
        Bool (*predicate )();
        char *arg ;
      display   指定到 X server 的连接。
      event_return   返回与相关结构匹配的事件。
      predicate   指定用来判断队列中的下一个事件是否匹配你所要的东西的过程。
      arg   指定由用户补充,将会发送给断言过程的参数。
      XIfEvent 函数只有当指定的断言过程为这个事件返回 True 才算完成,这表示队列中有一个事件匹配。如果 XIfEvent 阻塞等待另外的事件,那么它刷新输出缓冲区。XIfEvent 将匹配的事件从队列中移去并且将结构复制到客户程序补充的 XEvent 结构。
 
      为匹配事件检查队列,而并不阻塞的话,使用 XCheckIfEvent。
      Bool XCheckIfEvent(display, event_return, predicate, arg )
        Display *display ;
        XEvent *event_return ;
        Bool (*predicate )();
        char *arg ;
      display   指定到 X server 的连接。
      event_return   返回与相关结构匹配的事件副本。
      predicate   指定用来判断队列中下一个事件是否匹配你想要的东西的过程。
      arg   指定由用户补充,将发送给断言过程的参数。
      当断言过程找到一个匹配,XCheckIfEvent 复制匹配的事件到客户程序补充的 XEvent 结构中并且返回 True。(这个事件已经从队列中移出。)如果断言过程没有找到匹配的事件,XCheckIfEvent 返回 False,并且输出缓冲区将被刷新。所有早先存放在队列中的事件并不会被丢弃。
 
      为了匹配事件检查队列而又不用将事件从队列中移出,用 XPeekIfEvent。
      XPeekIfEvent(display, event_return, predicate, arg)
        Display *display;
        XEvent *event_return;
        Bool (*predicate)();
        char *arg;
 
 3. 使用窗口或者事件掩码选择事件
 
      XWindowEvent(display, w, event_mask, event_return )
        Display *display ;
        Window w ;
        long event_mask ;
        XEvent *event_return ;
 
      Bool XCheckWindowEvent(display, w, event_mask, event_return )
        Display *display ;
        Window w ;
        long event_mask ;
        XEvent *event_return ;
 
      XMaskEvent(display, event_mask, event_return )
        Display *display ;
        long event_mask ;
        XEvent *event_return ;
 
      Bool XCheckMaskEvent(display, event_mask, event_return )
        Display *display ;
        long event_mask ;
        XEvent *event_return ;
 
      Bool XCheckTypedEvent(display, event_type, event_return )
        Display *display ;
        int event_type ;
        XEvent *event_return ;
 
      Bool XCheckTypedWindowEvent(display, w, event_type, event_return )
        Display *display ;
        Window w ;
        int event_type ;
        XEvent *event_return ;
 
将事件放回队列
 
      要将事件放回事件队列,使用 XPutBackEvent。
 
      XPutBackEvent(display, event )
        Display *display ;
        XEvent *event ;
 
      XPutBackEvent 函数通过将事件复制到队列中从而将事件放置在显示的事件队列的前头。如果你读取事件,然后决定你宁愿稍候再去处理它,那么这个函数可能比较有用。对你可以连续调用 XPutBackEvent 的次数没有限制。
 
发送事件给其它应用程序
 
      要发送事件给指定的窗口,使用 XSendEvent。这个函数通常在 selection 的处理中。例如,当 selection 已经被转换并且作为 property 储存的时候,selection 的拥有者应当使用 XSendEvent 来发送 SelectionNotify 事件给请求者。
 
      Status XSendEvent(display, w, propagate, event_mask, event_send )
        Display *display ;
        Window w ;
        Bool propagate ;
        long event_mask ;
        XEvent *event_send ;
      display   指定到 X server 的连接。
       指定事件要发送到的窗口、PointerWindow、或者 InputFocus。
      propagate   指定一个布尔值。
      event_mask   指定事件掩码。
      event_send   指定要发送的事件。
 
      XSendEvent 函数标识目的地窗口,判断哪一个客户程序应当接受指定的事件,并且忽略任何活动的抓取。这个函数要求你发送一个事件掩码。这个函数使用 w 参数所标识的目的地窗口如下:
•如果 w 是 PointerWindow,目的地窗口就是包含鼠标指针的窗口。
•如果 w 是 InputFocus 并且如果焦点窗口包含鼠标指针的话,目的地窗口就是包含鼠标指针的窗口;否则,目的地窗口就是焦点窗口。
      要判断哪一个客户程序应当接收指定的事件,XSendEvent 对于传播参数的使用如下:

•如果 event_mask 是空集,事件应当发送给创建目的地窗口的客户程序。如果客户程序不再存在,就不用发送事件。
•如果 propagate 是 False,事件就会被发送给将目的地选择为 event_mask 参数中任何事件类型的每一个客户程序。
•如果 propagate 是 True 并且没有客户程序已经将目的地选择为 event_mask 中的任何事件类型,那么对于一些已经选择了 event_mask 中类型的客户程序,并且对于类型在其 do-not-propagate-mask 中的不可干预窗口而言,目的地应当被最接近于目的地的祖先所取代。如果没有这样的窗口存在,或者说如果窗口是焦点窗口的祖先,并且 InputFocus 最初被指定作为目的地,那么事件不会发送给任何客户程序。否则,事件会被传播到将最终的目的地选择为 event_mask 中指定类型的每一个客户程序。
      如果到包装协议格式的转换失败的话, XSendEvent 返回零,否则返回非零。
 
      XSendEvent 可以生成 BadValue 和 BadWindow 错误。
 
KeyPress、KeyRelease、ButtonPress、ButtonRelease、MotionNotif
 
      root, event: WINDOW
      child: WINDOW or None
      same-screen: BOOL
      root-x, root-y, event-x, event-y: INT16
      detail: <see below>
      state: SETofKEYBUTMASK
      time: TIMESTAMP
 
      在某个键或者鼠标按钮逻辑上改变了状态的时候,或者在鼠标的指针逻辑上移动位置的时候生成这些事件。如果设备事件处理被冻结的话,这些逻辑改变的生成可能滞后于物理上的改变。注意 所有的键都生成 KeyPress 和 KeyRelease,尽管这些键映射到编辑位。事件的来源是鼠标指针指进的窗口。接到报告相关事件的窗口是被调用的事件窗口。事件窗口是通过从源窗口开始并且从第一个客户程序在其上选择有兴趣的事件(所提供的没有干预的窗口阻止通过在其 do-not-propgagate-mask 中包含事件类型进行的事件生成)的窗口开始逐层进行查找而来的。用于报告的实际窗口可以通过活动捕获来进行修改,并且在键盘事件的情况下,可以通过焦点窗口来修改。
 
      root 是源窗口的根窗口,并且 root-x 和 root-y 都是在事件发生时刻相对于根原点的鼠标指针坐标。事件是事件窗口。如果事件窗口在同一个屏幕上是作为根窗口,那么 event-x 和 event-y 都是相对于事件窗口原点的鼠标指针坐标。否则,event-x 和 event-y 都是零。如果源窗口是事件窗口的下级窗口,那么孩子就被设置成作为源窗口祖先的事件窗口的孩子。否则,它被设置为 None。状态组件给出了事件之前的按钮和编辑键的逻辑状态。细节的组件类型随事件类型而变化:
 
Event  Component 
KeyPress, KeyRelease  KEYCODE 
ButtonPress, ButtonRelease  BUTTON 
MotionNotify  {Normal, Hint}

 
      MotionNotify 事件只是在窗口中的运动开始和结束时生成。运动事件的粒度并不能保证,但是客户程序对运动事件的选择保证在鼠标指针移动并且休息的时候至少得到一个事件。选择 PointerMotion 接收事件独立于鼠标指针的状态。通过选择一些 Button[1-5]Motion 的子集来代替,MotionNotify 事件将只会在一个或者多个指定的按钮被按下时才会接收到。通过选择 ButtonMotion,MotionNotify 事件将只是在至少有一个按钮被按下时就会接收到。类型总是 MotionNotify 的事件独立于选择。如果 PointerMotionHint 被选择,那么服务器会自由地只为事件窗口发送一个 MotionNotify 事件(带有详细的 Hint)给客户程序,指针离开事件窗口,或者客户程序发起 QueryPointer 或者 GetMotionEvents 请求。
 
选择事件
 
      有两种途径来选择你希望报告给你的客户程序的事件。一是在你调用 XCreateWindow 和 XChangeWindowAttributes 的时候设置 XSetWindowAttributes 结构的 event_mask 成员。另一个是使用 XSelectInput。
 
      XSelectInput(display, w, event_mask)
        Display *display;
        Window w;
        long event_mask;
 
      XSelectionInput 函数请求 X server 提供与指定的事件掩码相关的事件。最初,X 将不会报告任何这些事件。报告与窗口相关的事件。如果窗口并不对设备事件感兴趣,它通常传播到感兴趣的最近的祖先,除非 do-not-propagate 掩码禁止了它。
 
      设置窗口的事件掩码属性会覆盖任何以前对相同窗口的属性设置调用,而不是对其它的客户程序。多个客户程序可能对相同窗口选择相同的事件有以下的限制:
•多个客户程序在相同的窗口上选择事件,因为它们的事件掩码是不脱节的。当 X server 生成一个事件时,它会将这个事件报告给所有感兴趣的客户程序。
•一次只有一个客户程序可以选择 CirculateRequest、ConfigureRequest 或者 MapRequest 事件,这些是与事件掩码 SubstructureRedirectMask 相关的。
•一次只有一个客户程序可以选择 ResizeRequest 事件,它与事件掩码 ResizeRedirectMask 相关。
•一次只有一个客户程序可以选择与事件掩码 ButtonPressMask 相关的 ButtonPress 事件。
      服务器报告事件给所有感兴趣的客户程序。
 
      XSelectInput 可以生成一个 BadWindow 错误。
 
鼠标指针的剥夺
 
      Xlib 提供了用于控制来自指针输入的函数,通常是鼠标的指针。窗口管理器最经常使用这些功能来实现某些用户接口的风格。一些工具箱也需要将这些功能用于某些特殊用途。
 
      通常,一旦键盘和鼠标事件发生,X server 将它们递送给恰当的客户程序,这个客户程序由窗口和输入焦点所决定。X server 在事件递送方面提供足够的控制以允许窗口管理器来进一步支持鼠标以及不同的其它用户接口风格。许多这些用户接口中取决于事件的同步递送,鼠标指针和键盘事件的递送可以单独地进行控制。
 
      当鼠标按钮或者键盘按键被剥夺后,事件将被发送到剥夺它们的客户程序而不是正常情况下应该接收到它们的客户程序。如果键盘或者鼠标指针处于异步模式下,后续的鼠标和键盘事件将继续被处理。如果键盘或者鼠标指针处于同步模式,就没有进一步的事件要处理,直到剥夺的客户程序允许事件(参见 XAllowEvents)。在这段时间间隔内,键盘和鼠标指针认为是被冻结的。触发这个剥夺的事件也可以重放。
 
      注意如果设备事件处理被冻结的话,设备的逻辑状态(正如客户应用程序所看到)可能滞后于其物理状态 。
 
      有两种类型的剥夺:主动的和被动的。主动的剥夺发生在单个的客户显式地剥夺键盘或者鼠标指针(参见 XGrabPointer 和 XGrabKeyboard)的时候。被动的剥夺发生在客户程序在某个窗口中剥夺某个特定的键盘按键或者鼠标按钮,并且剥夺将会在这个按键或者按钮真正被按下的时候被激活。被动剥夺对于实现可靠的弹出菜单来说是很便利的。例如,你可以保证弹出是通过剥夺某个按钮请求的同步行为在松开指针按钮之前被映射。按下事件将会触发剥夺并冻结指针事件的进一步处理,直到你有机会去映射弹出窗口。
 
      对于许多操作来说,有一些函数接受一个时间参数。X server 在不同的事件中包括一个时间戳。有一个称为 CurrentTime 的特殊时间表示当前的服务器时间。X server 在输入焦点最后被改变时,在键盘最后被剥夺时,在鼠标指针最后被剥夺时,或者在某个 selection 最后被改变时维护这个时间。你的应用程序对某个事件的反应可能会慢。你常常需要用一些办法来指定在另一个应用程序控制键盘、指针或者 selection 的期间,你的请求不应当发生。通过在请求中提供来自事件的时间戳,如果某个人在这期间已经另外执行了一个操作,你可以安排这个操作并不生效。
 
      时间戳是一个以毫秒表达的时间值。它一般是自最后一次服务器重置起的时间。时间戳评估时间段(大约在 49.7 天之后)。服务给出它的由时间戳 T 表示的当前时间,总是通过将时间戳空间的一半视为在时间上比 T 要迟的方式解释来自客户程序的时间戳。命名为 CurrentTime 的时间戳值从不会由服务器生成。这个值被保留用于表示当前服务器时间的请求中。
 
      对于在这一部分的许多函数中,你发送鼠标指针事件掩码位。有效的指针事件掩码位是:ButtonPressMask、 ButtonReleaseMask、EnterWindowMask、LeaveWindowMask、PointerMotionMask、 PointerMotionHintMask、Button1MotionMask、Button2MotionMask、 Button3MotionMask、Button4MotionMask、Button5MotionMask、ButtonMotionMask 以及 KeyMapStateMask。对于本部分中的其它函数,它发送按键掩码位。有效的按键掩码位是:ShiftMask、LockMask、 ControlMask、Mod1Mask、Mod2Mask、Mod3Mask、Mod4Mask 以及 Mod5Mask。
 
      要剥夺鼠标指针,使用 XGrabPointer。
 
      int XGrabPointer(display, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor, time )
        Display *display ;
        Window grab_window ;
        Bool owner_events ;
        unsigned int event_mask ;
        int pointer_mode , keyboard_mode ;
        Window confine_to ;
        Cursor cursor ;
        Time time ;
      display   指定到 X server 的连接。
      grab_window   指定剥夺的窗口。
      owner_events   指定一个布尔值表示是否照常报告指针事件或者如果是通过事件掩码选择的话,遵照剥夺窗口来报告。
      event_mask  指定哪些指针事件要被报告给客户程序。掩码是有效鼠标指针事件掩码位的“或”(OR)位运算。
      pointer_mode  指定进一步的鼠标指针事件处理。你可以发送 GrabModeSync 或者 GrabModeAsync。
      keyboard_mode  指定键盘事件的进一步处理。你可以发送 GrabModeSync 或者 GrabModeAsync。
      confine_to  指定限制鼠标指针的窗口或者 None。
      cursor  指定在剥夺期间显示的光标或者 None。
      time  指定时间,你可以发送一个时间戳或者 CurrentTime。
 
      XGrabPointer 函数主动地剥夺鼠标指针的控制并且如果剥夺成功的话返回 GrabSuccess。进一步的鼠标指针事件只报告给进行剥夺的客户程序。XGrabPointer 通过这个客户程序覆盖任何主动的剥夺。如果 owner_events 是 False,报告关于 grab_window 的所有生成指针事件并且只报告通过 event_mask 选择的事件。如果 owner_events 是 True 并且如果生成的指针事件会正常地报告给这个客户程序的话,它就照常报告。否则,报告产于 grab_window 的事件并且只报告由 event_mask 选择的事件。对于 owner_events 的两个值的任何一个来说,没有报告的事件都被丢弃。
 
      如果 pointer_mode 是 GrabModeAsync,指针事件处理照常继续。如果指针当前被这个客户程序冻结,对于指针的事件处理就被挂起。如果 pointer_mode 是 GrabModeSync,作为客户应用程序来看,指针的状态看来是冻结的,并且 X server 并不进一步地生成指针事件,直到进行剥夺的客户程序调用 XAllowEvents 或者直到指针的剥夺被释放。当鼠标指针被冻结时,实际上的指针改变并不会丢失;它们被简单地放置在服务器的队列中以备后来处理。
 
      如果 keyboard_mode 是 GrabModeAsync,键盘事件处理不会因剥夺的激活所影响。如果 keyboard_mode 是 GrabModeSync,作为客户应用程序来看,键盘的状态看来是冻结的,并且 X server 不会生成进一步的事件,直到进行剥夺的客户程序调用 XAllowEvents 或者直到指针的剥夺被释放。当鼠标指针被冻结的时候,实际上的键盘改变并不会丢失;它们被简单地放置在服务器的队列中以备后来处理。
 
      如果指定了光标,它就会被显示,而不管鼠标指针指在什么窗口内。如果指定的是 None,当指针指向 grab_window 或者其子窗口之一时,显示用于这个窗口的正常光标;否则,显示用于 grab_window 的光标。
 
      如果指定了 confine_to 窗口,指针被限制停留在包含它的那个窗口内。这个 confine_to 窗口需要与 grab_window 没有任何关系。如果指针最初并不在 confine_to 窗口中,在剥夺激活之前它就自动地被最近的边界所弯曲,并且进入/离开事件照常生成。如果 confine_to 窗口随后被重新配置,指针就被自动弯曲,作为必要的条件,要将其保持在包含它的窗口中。
 
      参数 time 允许你去避免某些在如果应用程序花费了较长的时间进行响应下或者如果有较长的网络延迟下出现的情况。考虑你有两个应用程序的情况,这两个应用程序在点击的时候正常地剥夺指针。如果这两个应用程序指定了来自事件的时间戳,第二个应用程序可能会更快地唤醒并且在第一个程序之前成功地剥夺指针。第一个应用程序然后将会得到一个其它应用程序在它的请求被处理之前已经剥夺了指针的标志。
 
      XGrabPointer 生成 EnterNotify 和 LeaveNotify 事件。
 
      如果 grab_window 或者 confine_to 窗口并不是可视的,或者如果 confine_to 窗口完全位于根窗口的边界之外,XGrabPointer 失败并且返回 GrabNotViewable。如果指针被某些其它的客户程序主动地剥夺,它会失败并且返回 AlreadyGrabbed。如果鼠标指针被其它应用程序的某个剥夺所冻结,它会失败并且返回 GrabFrozen。如果指定的时间早于 last-pointer-grab 时间或者迟于当前 X server 的时间,它会失败并且返回 GrabInvalidTime。否则,last-pointer-grab 时间被设置为指定的时间(CurrentTime 被当前 X server 时间所取代)。
 
      XGrabPointer 可以生成 BadCursor、BadValue、和 BadWindow 错误。
 
      要取消剥夺指针,使用 XUngrabPointer。
 
      XUngrabPointer(display, time )
        Display *display ;
        Time time ;
      display   指定到 X server 的连接。
      time   指定时间。你可以发送一个时间戳或者 CurrentTime。
 
      如果这个客户程序通过 XGrabPointer、XGrabButton、或者某个一般的键被按下来主动地剥夺,XUngrabPointer 函数释放指针和任何排进队列的事件。如果指定的时间早于 last-pointer-grab 或者晚于当前 X server 的时间,XUngrabPointer 并不释放指针。它也生成 EnterNotify 和 LeaveNotify 事件。如果主动的指针剥夺的事件窗口或者 confine_to 窗口变成不可视的或者如果窗口的重新配置引起 confine_to 窗口完全处于根窗口的边界之外的话,X server 自动地执行一个 UngrabPointer 请求。
 
      要改变激活的指针剥夺,使用 XChangeActivePointerGrab
 
      XChangeActivePointerGrab(display, event_mask, cursor, time )
        Display *display ;
        unsigned int event_mask ;
        Cursor cursor ;
        Time time ;
      display   指定到 X server 的连接。
      event_mask   指定哪些指针事件被报告给客户程序。掩码是有效指针事件掩码位的“或”(OR)运算。
      cursor   指定要被显式的光标或者 None。
      time   指定时间。你可以发送时间戳或者 CurrentTime。
 
      如果鼠标指针主动地被客户程序所剥夺并且如果指定的时间不早于 last-pointer-grab 并且不晚于当前的 X server 的时间,那么 XChangeActivePointerGrab 函数改变指定的动态参数。这个函数对于 XGrabButton 的被动参数不起作用。对于 event_mask 和 cursor 的解释和在上面说明的 XGrabPointer 中一样。
 
      XChangeActivePointerGrab 可以生成 BadCursor 和 BadValue 错误。
 
      要剥夺鼠标指针的按钮,使用 XGrabButton。
 
      XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor)
        Display *display;
        unsigned int button;
        unsigned int modifiers;
        Window grab_window;
        Bool owner_events;
        unsigned int event_mask;
        int pointer_mode, keyboard_mode;
        Window confine_to;
        Cursor cursor;
      display  指定到 X server 的连接。
      button  指定要被剥夺的指针按钮或者 AnyButton。
      modifier  指定一组按键掩码或者 AnyModifier。这个掩码是有效的按键掩码位的“或”(OR)运算。
      grab_window  指定剥夺窗口
      owner_events  指定一个布尔值标识指针事件是否照常报告或者只报告由事件掩码选择的关于剥夺窗口的事件。
      event_mask  指定哪些事件要报告给客户程序。掩码是有效指针事件掩码位的或(OR)运算。
      pointer_mode  指定鼠标指针事件的进一步处理。你可以发送 GrabModeSync 或者 GrabModeAsync。
      keyboard_mode  指定键盘事件的进一步处理。你可以发送 GrabModeSync 或者 GrabModeAsync。
      confine_to  指定窗口以限制鼠标指针的指向或者 None。
      cursor  指定要被显示的光标或者 None。
 
      XGrabButton 函数建立一个被动的剥夺。以后,指针被主动剥夺(用 XGrabPointer),last-pointer-grab 时间被设置为按钮被按下的时间(在 ButtonPress 事件中传送),并且如果下列所有的条件值都是真的话,ButtonPress 事件就被报告:
•指针没有被剥夺,并且指定的按钮逻辑上是当指定的编辑(modifier)键被逻辑上按下时才被按下,并且没有其它按钮或者编辑键逻辑上被按下。
•这个 grab_window 包含鼠标指针。
•这个 confine_to 窗口(如果有)是可视的。
•在相同的按钮/按键组合上的被动剥夺并不会存在于 grab_window 的任何祖先窗口上。
 
      剩余参数的解释与 XGrabPointer 一样。主动的剥夺在当鼠标指针的逻辑状态上所有的按钮都被释放时自动地终止(独立于逻辑编辑键的状态)。
 
      注意如果设备事件处理被冻结的话,设备的逻辑状态(作为客户应用程序来看)可能滞后于物理状态。
 
      这个请求会覆盖所有通过相同的客户程序在相同窗口上的用相同的按钮/按键组合产生的所有以前的剥夺。值为 AnyModifier 的编辑标志等于发起对所有可能编辑标志组合(包括非编辑标志的组合)的剥夺。并不要求指定的所有编辑标志当前都被指派了 KeyCode。值为 AnyButton 的按钮等于发起对所有可能按钮的请求。否则不要求指定的按钮当前被指派了一个物理按钮。
 
      如果一些其它的客户程序已经用相同的按钮/按键组合在相同的窗口上发起了一个 XGrabButton,那么会产生一个 BadAccess 错误。当使用 AnyModifier 或者 AnyButton 时,如果有对于任何组合有冲突的剥夺的话,那么请求会完全失败,并且产生一个 BadAccess 错误(没有建立起剥夺)。XGrabButton 对于主动的剥夺没有作用。
 
      XGrabButton 可以生成 BadCursor、BadValue、以及 BadWindow 错误。
 
      要取消对指针按钮的剥夺,使用 XUngrabButton。
 
      XUngrabButton(display, button, modifiers, grab_window)
        Display *display;
        unsigned int button;
        unsigned int modifiers;
        Window grab_window;
      display  指定到 X server 的连接。
      button  指定 要被释放的按钮或者 AnyButton。
      modifiers  指定一组按键掩码或者 AnyModifier。掩码是有效位按键掩码位的或(OR)运算。
      grab_window  指定剥夺窗口。
 
      如果窗口被这个客户程序剥夺的话,XUngrabButton 函数释放在指定窗口上的被动按钮/按键组合。值为 AnyModifier 的编辑标志等于发起对所有可能的编辑组合的取消剥夺请求。值为 AnyButton 的按钮等于发起对所有可能按钮的请求。XUngrabButton 对于主动的剥夺没有作用。
 
      XUngrabButton 可以生成 BadValue 和 BadWindow 错误。
 
键盘剥夺
 
      Xlib 提供用于剥夺和取消剥夺键盘以及允许事件的函数。
 
      int XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, time )
        Display *display ;
        Window grab_window ;
        Bool owner_events ;
        int pointer_mode , keyboard_mode ;
        Time time ;
      display   指定到 X server 的连接。
      grab_window   指定剥夺窗口。     
      owner_events   指定一个布尔值指示键盘事件是否照常报告。
      pointer_mode   指定进一步的指针事件处理。你可以发送 GrabModeSync 或者 GrabModeAsync。
      keyboard_mode   指定进一步的键盘事件处理。你可以发送 GrabModeSync 或者 GrabModeAsync。
      time   指定时间。你可以发送一个时间戳或者 CurrentTime。
 
      XUngrabKeyboard(display, time )
        Display *display ;
        Time time ;
      display   指定到 X server 的连接。
      time   指定时间。你可以发送时间戳或者 CurrentTime。
 
      要被动地剥夺键盘的某个键,使用 XGrabKey。
 
      XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode)
        Display *display;
        int keycode;
        unsigned int modifiers;
        Window grab_window;
        Bool owner_events;
        int pointer_mode, keyboard_mode;
      display  指定到 X server 的连接。
      keycode  指定 KeyCode 或者 AnyKey。
      modifiers   指定一组按键掩码或者 AnyModifer。掩码是有效按键掩码位的或(OR)运算。
      grab_window  指定剥夺窗口。
      owner_events  指定一个布尔值来标识键盘事件是否照常报告。
      pointer_mode  指定对指针事件的进一步处理。你可以发送 GrabModeSync 或者 GrabModeAsync。
      keyboard_mode  指定对键盘事件的进一步处理。你可以发送 GrabModeSync 或者 GrabModeAsync。
 
      要取消剥夺一个按键,使用 XUngrabKey。
 
      XUngrabKey(display, keycode, modifiers, grab_window )
        Display *display ;
        int keycode ;
        unsigned int modifiers ;
        Window grab_window ;
      display   指定到 X server 的连接。
      keycode   指定 KeyCode 或者 AnyKey。
      modifiers   指定一组按键掩码或者 AnyModifier。掩码是有效按键掩码位的或(OR)运算。
      grab_window   指定剥夺窗口。
 
      为了允许进一步的事件在设置被冻结时可以被处理,使用 XAllowEvents。
 
      XAllowEvents(display, event_mode, time)
        Display *display;
        int event_mode;
        Time time;
      display  指定到 X server 的连接。
      event_mode  指定事件模式。你可以发送 AsyncPointer、SyncPointer、AsyncKeyboard、SyncKeyboard、ReplayPointer、 ReplayKeyboard、AsyncBoth、或者 SyncBoth。
      time  指定时间。你可以发送一个时间戳或者 CurrentTime。
 

0

  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有