x Windows 50001

download x Windows 50001

of 5

Transcript of x Windows 50001

  • 8/7/2019 x Windows 50001

    1/5

    Keyboard and Mouse Eve nt Prop agation

    Whenre porting B uttonPress, ButtonRele ase, KeyPress, KeyRelease , and MotionNoti fy .events,the X server first determines which window should receive the event. For k~yboard events , this isthewindow with the input focus. For mouse events, this i s a visible window, lowest i ri the hierarchyofwindows that enclose the mouse pointer . The server checks the event_mask of this window tc

    determine if the window accepts this event. If it does, the server reports the event for this windo w.In this case, this window is the event window --the window to which the . event is reported.

    Ifthis window does not request the event, the server does not discard the event . Instead, it propa -gatesthe event up the hierarchy. The first step in the propagation is to send the event to the parent.Ihhe pare nt window accepts the event, the server reports the event to it . The event data structuref orthese keyboard and mouse events includes a subwindow field, in which the server reports thechildwindow where the event actually occurred . If the immediate parent does not accept the event,it issent to the nex t higher level , until the server encounters a window that h as selected the event or

    onethat stops the propagation of the event. The server discards the event only if it cannot find an ywindowthat ha s requested the event .

    Theprogrammer can control the propagation of keyboard and mouse ev ents . By default, keyboardandmouse events propagate up the window hierarchy, but a fi eld named do_not_propagate_mask inthe window attribute controls this feature (see the XWindowAttributes structUre in Chapter 7).If you do not want an event to propagate to the ancestors of a window, set thedo_not_propagate_mask of that window to that event 's mask . Use the same names you use whenselecting events with XSelectInput (see Table 6.3 in Chapter 6) . For example, if you wantButtonPress and ButtonRelease events to stop at the window win you can use the following

  • 8/7/2019 x Windows 50001

    2/5

    ButtonPress and ButtonRelease events to stop at the window win you can use the following

    ButtonPress and ButtonRelease events in the outer window only . When the user presses on o neof the menu items, the events are reported to the outer window , but the event's information in di-cates the subwindow where it actually occurred . You then can use this information to process t hemenu s election.

    . It sends to the server any X protocol requests waiting in Xlib's buffer . This feature is handybecause, unless this buffer is flushed, the effect of drawing functions does not appear onthe screen. You can call XFlush to perform the operation, but inclusion of this task inXNextEvent makes the flushing almost automatic, because most applications rely onXNextEvent to get events from Xlib.

    . XNextEvent looks for any events waiting in Xlib 's event queue . If there is an event ,XNextEvent returns after copying the information abour the event into the XEvent union

    whose address you provide as an argument to XNextEvent . If no events are available yet,XNextEvent waits until an event arrives from the server . XNextEvent "blocks" until itreceives an event.

    Unsolicited Events: MappingNotify and ClientMessageRe call .that the X server never reports events that were not explicitly solicited . There are, howeve r,two rypes of events that are always sent to applications. The first one is the MappingNoti fy eve nt.This event is generated when any application rearranges the keyboard keycodes or changes thenumbering of the mouse buttons . It makes sense because all applications using a display share thekeyboard and the mouse. It is easy to handle this event. Put the following case statement in theswi tch statement of the main event handling loop:

    Some applications have a problem with the fact that XNextEvent does not return until an eventbecomes available. For example, suppose your application is performing some lengthy computa-tions and displaying the results as work progresses. If you want to do the computation and still re-spond to the user's input (perhaps a click on a Cancel button), you cannot use XNextEvent.

    To achieve your goal, you must break the computation into smaller chunks. Mter you organize thework into smaller portions, you need ways to check whether any events are waiting and to processthe waiting events. If no events are available, you can perform a small chunk .of computation. Youcan use the XEventsQueued function together with XNextEvent to do the job:

    case MappingNotify:XRefreshKeyboardMapping(&theEvent);break;

    The examples shown thus far lack this code, but you should include this in all your X applications.

    Another type of unsolicited event delivered to your application is a ClientMessage event sent byanother X client using the XSendEvent f unction . The interpretation of the information passed bythese events is up to the sender and the receiver . Window managers often use ClientMessage eve nts

    to communicate with applications. The exact message type and the recommended handling of t heevent depends on the window manager . Of course, even when ClientMessage events reach yo urapplication, your application is not required to do anything with these events .

    X E ve n t t h eE v en t ;Disp lay * theDisp lay ;i n t A p pD o ne , e v en t s_ p en d in g ;

    AppDone = 0;whi le ( !AppDone){

    / * P r oc e ss a l l c u r re n t e v en t s i n t h e q u eu e * /i fevents_pending XEventsQueued( theDisp lay,

    QueuedAfterReading = = 0){

    / * P e r fo r m a s m a l l p a rt o f y o u r c o mp u ta t io n s i n cl u di n g* any drawing opera tions*/

    When the X server sends events to the application, Xl ib automatically saves the events in a queue.

    Your programs have to call certain routines to get the events from the queue . So far , the e xampleprograms in this book have used the XNextEvent function to get events from Xlib 's event queue:

    Display * theDisp lay ;X E ve n t t h eE v en t ;

    }/ * P r oc e ss a l l w a it i ng e v en t s * /

    whi le (events_pending - ){

    XNextEvent ( theDisplay, &theEvent ) ;sWitch(theEvent . type){

    XNextEvent ( theDisplay, &theEvent ) ;

    This code performs two tasks :

    case MappingNotify:XRefreshKeyboardMapping(&theEvent);break;

    / * H a n dl e o t he r e v en t s . . . * /case But tonPress :

  • 8/7/2019 x Windows 50001

    3/5

    0()'J-kChapter Eight: HandlingE vents

    f * Handl e event s o cc ur r in g i n th is w in do w * f i f ( th e Event.xany.win dow = = this_window){

    swi t ch(the Event.type){

    ca se Expose:if ( th eEvent .xex pos e.count = = 0){

    }

    break;

    As you can see, the field theEvent. xexpose. count r epres ents the count of Expose ev ents. Whenthe count is zero, you can clear the w indow and draw the graphi cs and text~that sh ould appear inthe window . This part of the operation depend s on the appl icat ion. Chapter 9, "Dra wing Graph -ics," provide s more det ails on E xpose events.

    Recall also that so me X displa ys m ay have off- screen memor y k nown as "backing store" that en -ables them to save the co ntent s of a w indow when it gets ob scured. With back ing store, the servercan r efre sh the win dow automat ically wh en it beco mes vis ible a gain . In the se cases, t he server doesnot send any Expose - events, which, in t urn, spares t he application t he compu tationa l burden of

    redrawi ng itsw indo ws Because no t all di splays have backing s tore you should always includ e code

  • 8/7/2019 x Windows 50001

    4/5

    effect of clicking on a window. On the Macintosh and on Microsoft Windows, YQlLStartap plica -tions by double-clicking . on their icons. This requires two clicks in quick succes;ion with the poi nterat ~e sam e!'-o-ca-t-l-o-n-.-- = ----

    w i n_ x , w i n_ y ;keys_buttons;

    / * P o si t io n i n w' s f ra me * // * In fo o n m o us e b u tt on s * /

    In the1- Window Sys tem, there are no events equivalent to button clicks or doub le-clicks. I nst ead,the X serverreports a few basicmO lJ~n ts: ~hen a but ton iU' resse~and released, wh~ n t~e mo useis moved, and when the mouse pointer enters or leaves a window . If you understan d whe n thesebasic events are generated and how they are reportea ;you can write your own event hand ling codeto give the appearance of a button 0ck or doubl~- .~;li~k . /

    i f ( !XQueryPoin ter ( theDisp lay, w, &root, &c hi l d , & r o o t _x , & r o ot_y,&win_x, &win_y, &keys_but tons

    {/ * P o in t e r i s n o t o n t h e s c r e e n w h e re w i nd o w w i s * /}

    uttons, Pointer, and Cursor

    Here, w is the window in whose coordinate frame you want to find the pointer's position.XQueryPointer returns a zero if the pointer is not on the screen where window wis displayed. Inthis case, in the root variable, it returns the 10 of the root window on the screen where the pointerappears.

    If successful, XQueryPointer provides the information in a set of variables . You have to declarethese variables and pass their addresses as arguments to the function. In root and child, you getback the window 10 of the root window and any visible subwindow of wthat contains the pointer .If the pointer is in wand not in any of its child windows, child will be set to None.The coordinatesof the pointer with respect to the root window are returned in root .:...xand root_y, and win_x,win _yare the coordinates in w's frame.

    ,

    The number of mouse buttons varies from one workstation to another. The mouse in the AppleMacintosh has only one button; the Microsoft mouse, prevalent in the MS-DOS and Mic rosoftWindows world, uses two buttons. Most UNIX workstations and some MS -DOS systems use athree-button mouse.~ allows for mice with up to five buttons, named Button1 through B uttonS.Usually, the mouse buttons are numbered from left to right, but a programmer can ca ll theXSetPointerMapping function to change the orde~lng. - - '0

    The pointer refers to the graphical indication of the mouse's position in the display screen. The cursor is the actual graphical object that determines the appearance of the pointer in the screen.

    The keys_buttons variable is a bit mask that indicates which mouse button and which modifierkey (Shift, Ctrl, Meta, or Alt) is pressed at that moment. To decipher this inforination, you have toperform bitwise-AND of keys_buttons with bitmask names defined in the header ftle .For example, to see if Button1 is pressed, you might write the following:

    if (keys_buttons & Button1Mask){

    / * Yes , b u t to n 1 i s p r e s se d * /Although the X server automatically moves the pointer to track the movements of the mouse , youhave control over several aspects of the pointer . You Can, for example, call the XWarpPointer func-tion to move the pointer forcibly to a specified location On the screen. This can be disconcertin g tothe user; therefore, you probably should not warp the pointer unless absolutely necessary fof"s ometask in your application.

    Two other parameters of the pointer, acceleration and threshold, can also be set by programm ers.Acceleration refers to how fast the pointer moves as you move the mouse. The acceleration is a p-plied only when the mouse movement exceeds the threshold. You can use XGetPointerContr oland XChangePointerControl to change these parameters, but you rarely need to do so. Many us ersrun the utility program name xset to set the acceleration and threshold . On most UNIX wo rk-

    stations, you should be able to get further information on xset by typing the command man xse tat the shell prompt.

    Because xaueryPointer has to get its information from the X server, each call to thisfunction requires a costly round trip over the network connection to the server. Thus,excessiveuse ofxaueryPointer can hurt the performance of your application. To keeptrack of mouse positions in a window, -use the MotionNotify event instead.

    *theDisplay;w,root , ch i ld ;roo t_x , roo t_y,

    / * I d e nt i f ie s t h e X s e r v e r * // * W in do w o f i nt er es t * //* Fo r ret urn valu es * //* Pos iti on in roo t * /

    After you find the coordinates of the pointer in one window's coordinate frame, you can convert itto another window's frame by calling XTranslateCoordinates. Unfortunately, this conversion isalso performed by sending a protocol request to the server and getting a reply back . Thus,XTranslateCoordinates is as costly as using xaueryPointer.

    One interesting use of XTranslateCoordinates is to determine the window where a point lies.For example, if you know the coordinates x and y of a point, relative to the root window, you candetermine the ID of the top-level V i"indowcontaining the point:

    Sometimes your application may have to determine the current position of the mouse pointer. XlibincluUe .sthe function XQueryPointer for this purpose:

    DisplayWindow

  • 8/7/2019 x Windows 50001

    5/5

    Wi ndowin ti nt

    top leve l ;x , y;xx, yy;

    t * Wi n d ow t h at c ontain s th e po i nt ( x , y) * tt * Coo r di na te s o f t he p oi nt o f i nt er e s t * tt * S t o ra g e f o r v a l ue be in g di sc a r de d * t

    XC o lo r f g colo r , bg co lo r ;Cur s or a r r ow _cursor ;

    t * Col or s i n XColor s t ruc ture * tt * Cur so r wh o s e c o l o r i s s e t * t

    XTranslateCoor di nates(theDispla y, Def a ul t Root Window( t he Di splay) ,DefaultRootWindo w(theDisplay) , x , y , & x x , & y y, & toplevel ) ;

    On return from XTrans lateCoordin ates, the vat iable topl evel contains the 1 0 of the w indo wwhere the point (x , y) lies. If the point l ies in the root windo w, but not in any top-lev el subw indow,the returned 10 will be the constant N one.

    To specif Y the color, you have to use RGB va lues. For more info rmation on color, see Chapte r 11 ,"Usi ng Color in X."

    You can useyour own source and mask b itmaps to define a c ursor . After you have the two pixm aps-bitmaps are pixmaps of depth one -you can use XCre atePixmap Curso r to c rea te a new c ursor .This function ne eds the two p ixmap s, the foreground and background colors , and the coordinatesof the hotspot :The cursor determine s the on- screen appearance o f the po inter. In X, a cur sor is defined by a s ource

    bitmap , a ma sk bitm ap, foregr ound and backgr ound color s specified as RGB values, an d a hotspot.You can thin k of the bitm aps as a sm all rect angular array of Is and Os(usual ly 16x16 or 3 2x32).When draw ing the curs or, the server paints t he pi..xelscor responding to Is using the fore groundcolor; pixels at locat ions w ith Os appe ar in the back ground color . The mask bitmap determi nes theoutline with in whic h the cursor shape is draw n. The hotsp ot is a point that defines the loc ation of the pointe r in th e scree n. For ma ny cursor shap es, the hotspot is at the center of the cursor's birmap.For an arrow cursor , die hot spo t is the p oint of the arrow.

    You can as sign a cur sor to any windo w in your applic ation. Typi cally, you create a new curs or from

    a standard curs or font and as sign it to a window:#i n c lude C u r so r a r r ow _ c ur s o r;

    Disp l ayCur s orPixma pXColoruns igne d in t

    *t heDi~ p l ay ;my _cursor ;so urce , mask;f gc olo r , bgcolor;x _hot, y _hot;

    my _curso r = XCreatePix mapCursor( t heDisplay , source , maSk,&fgcolor, &bgcolor, X_hot , y_hot ) ;

    Another way to get a curs or is t o select a specific c haracter from a font and use the bit map of that

    character as a cursor . Befo re using the f ont, you have to load the f ont by calling Xl oadF ont (seeChapte r 10 , "Drawi ng Te xt"). Then you can create the cursor usi ng the f unct ionXCreateG.lyphCursor ( see it s reference page in Appendix A f or inf ormation on call ing this func-tion).

    XDefineCur' s or ( theDisplay , my_window, ar row_curs or );

    Once this is done, t he cur sor shap e changes to the arrow cursor when the po inter enters the wi n-dow my_wi ndow.T his selection rema ins in effect until you undefin e the cursor for that window bycalling XU ndefineCur sor. Wh en you remove the cursor from a w ind ow, the serv er disp lays thecursor of its parent when the pointe r is in this windo w.

    Note that th e second argu ment to XCreat eFontCursor specifies the c ursor shape with a symbo lic

    name. These names are def ined in the header file .Af ter assigni ng a cursor to a window , ifyou d o not intend to r efer to it a ny more, you can f ree thecurso r by call ing XFreeCursor. Any win dow that di splays thi s cursor will contin ue to do so. Theserverwill get rid of the curs or only after that cursor isnot defined for anywindow . Once you un definea curso r, you must not ref er to that cursor' s 10 ag ain.

    In the text of this book, som e Xlib functions are described in derail; many others arementioned b rie f ly. If y Olln eed more informat ion on the calli ng synta x:o f any funct ion,please cons ult the r eferen ce pages i n Appendix "'A, "Xlib Fu nctions." F or quick a ccess to th eXlib fu nctions, check Ap pendix I, "Xlib Referen ce."

    ButtonPres s and ButtonRelease Events /' ~Af ter you know how to create and co ntrol the cursor , you are re~o use,the mou se in a user in-terface. For a sim ple case, in whic h you want som ething done whe n the user pres ses the mou se bunonin a spec ific wind ow, y ou can handle t he Butt~ on lyai 1(f ignore the 'Buttoj iReleaseevent s. If you want to SU PPD rt mouse butto n click s and dou ble-click s, you have to process bothbutton events . '--------

    When a cursor i s creat ed, it has, by defa ult, a blac k foregroun d and a white back ground color. Tocha nge the co lor of a cursor, use the XRec olorCurso r fu ction :

    The file xbut ton. c shown in Listing 8 .3 shQwSan exam ple of handling mo use bunonpress events .To h andl e the event ; you hav e to look t~r the event type ButtonPr ess. Once you get t he event,you ca n perform the act ion associated with the bunonp ress .