📄 original_mini-x.txt
字号:
MINI-X TUTORIAL David I. Bell 19 May 91This is a simple tutorial on using the mini-X graphics system. Much of thisis a lot easier to understand if you are familiar to X. I am not going totry to explain every concept in detail here, nor how to put it all togetherto make really fancy programs. Instead, I am only going to tell you justenough to let you make some simple graphics programs which work. Experiencewith simple test programs will enable you to build much fancier graphicsprograms much easier than trying to decipher what I could tell you.I am assuming that you basically know what a screen, pixels, colors,keyboards, mice, buttons, and windows are. However, you probably don'tknow exactly what the properties of windows in this system are. Also, youmight not know two other concepts which are important here, which aregraphics contexts and events. So these things will be explained in thistutorial.WINDOWSWindows are rectangular areas which can be drawn into. Windows have aposition, specified by the x and y coordinates of their upper left corners,and also a size, specified by their width and height. Windows are arrangedin a tree structure, with the parent windows controlling the child windows.The top of the tree is known as the root window. The root window is alwayspresent, and represents the total screen area.Each child window is clipped by its parent window. This means that a windowcan be very large, but the only part of the window that can ever be seen isthe part which shows through its parent window. This applies recursively,so that all of the parents of a window limit its visibility. The positionof a window is specified relative to its parent, and not absolutely. Thismeans that for example, when a window is moved, then all of its children willmove with it. The position of a window can be negative.Windows which have the same parent can clip each other. That is, there is adefined order among the children of a window as to which is more important.If two sibling windows overlap, then the more important window will be visiblein preference to the less important window. The precedence of visibilityof siblings can be dynamically adjusted. Clipping can also occur on a windowby earlier siblings of any of the window's parents.Windows can be mapped or unmapped. Unmapped windows are not visible, andcause no events. They can be thought of as "in storage" or offscreen.When a window is mapped, then it can become visible on the screen. Childrenof an unmapped window are implicitly also unmapped. So a window is notvisible until it and all of its parents are mapped. A newly created windowstarts off unmapped.Windows have a background color. A newly mapped window is filled with itsbackground color. Clearing the window later, or having obscured portionsof the window become visible again, will fill the region with the background.The client program can then draw into the window to make it look correct.Windows may have a border. A border is a set of rectangles adjacent to thefour sides of the window which is drawn in a specified color, with aspecified width. This makes pretty lines around the window, for example.The border cannot be drawn in by the program. Borders are optional, sothat a window with a border width of zero has no border at all. Bordersare "around" the window, so that they do not affect the coordinates of thewindow. Whether or not a window has borders, its position determines thelocation of the upper left corner which can be drawn into.Windows can have a cursor associated with them. The graphics server tracksthe location of the mouse, and maintains the position of a graphics cursoron the screen. This cursor can automatically change its shape and colors asit moves between different windows. The use of different cursors for differentwindows can be used to provide a powerful clue to the user as to what willhappen if a mouse button is pressed in a window. Newly created windowsinherit the same cursor as their parent.There are two types of windows, input-output and input-only windows.Input-output windows are normal windows which are visible and can be drawninto. Input-only windows are invisible, have no border, and cannot bedrawn into. Their purpose is to catch events, and to enable the cursorto be changed in different regions of a visible window. The only childrenof input-only windows are also input-only windows.Windows are identified by integers called window ids. The root window hasa constant window id value of GR_ROOT_WINDOW_ID. The root window does notneed creating, and cannot be unmapped, moved, resized, or destroyed.However, it can be drawn into and events can be delivered to it. New windowscan be created from existing windows. Their window ids are not constants,but once created the window id remains until the window is destroyed. Windowids are not reused as windows are created and destroyed.GRAPHICS CONTEXTSWhen drawing objects such as lines, there are many parameters that can bespecified for the function call that affect the operation. Besides theminimum information needed for the function such as the endpoint coordinates,there are extra parameters that are less important and less variable.Examples of these extra parameters are color, width (thin or thick), style(dashed, dotted), and drawing operation (setting, XORing). Instead ofrequiring the specifying of each of these extra parameters for every functioncall, graphics contexts are used. Graphics contexts are just a collectionof specific combinations of these extra parameters. The many possibleextra parameters to each function are replaced by just one extra parameter,which is the graphics context.For example, instead of a function call like: drawline(window, x1, y1, x2, y2, color, width, style, operation);you have instead drawline(window, gc, x1, y1, x2, y2),where the graphics context contains within itself the parameters color, width,style, and operation.Graphics contexts are stored in the graphics server, and are identified byunique numbers in a way similar to window ids. Your program must allocategraphic contexts, which then can be used in drawing functions. A newlyallocated graphics context is supplied with default parameters, such as aforeground color of white, drawing operation of setting, and width of 0.You can modify the parameters associated with the graphics context one byone, by for example, setting the foreground color to black.A single graphics context could be used for every drawing operation byconstantly setting the parameters associated with it to the values neededfor each drawing call. But this is inefficient. The reason that multiplegraphics contexts can be allocated is so that you can minimize the setting oftheir parameters. By presetting the parameters of several graphics contextsto commonly used values in your program, you can avoid changing them later.For example, you can call one graphics context white_gc, and another graphicscontext black_gc, and then use the correct graphics context in the drawingfunctions to draw in either black or white.The parameters contained within a graphics context are currently thefollowing:Drawing mode.Specifies the operation performed when drawing each pixel. One of: GR_MODE_SET draw pixels as given (default) GR_MODE_XOR draw pixels using XOR GR_MODE_OR draw pixels using OR GR_MODE_AND draw pixels using ANDText font.A small integer identifying the font for drawing text. The first few arebuilt-in to the device driver, others must be loaded by the graphics server.The default font is 0.Foreground color.The color that is used to draw almost all objects with, such as lines,points, ellipses, text, bitmaps, and filled areas. Default is white.Background color.The color used for some functions in addition to the foreground color.For bitmaps and text, this is the color used for the zero bits. Thedefault background color is black. The drawing of this color can bedisabled by the next parameter.UseBackground flag.This is a boolean value which indicates whether or not the backgroundcolor is actually to be drawn for bitmaps, text, and the GrArea8 function.The default is GR_TRUE.EVENTSEvents are the way in which the graphics system notifies your programof asychronous changes in the state of the screen, mouse, or keyboard.Whenever the state changes, your program is notified of this change andcan act on it. The word "event" is used both for the actual changethat took place, and also for the data that is returned to your programwhich describes the change.Events are generated for various different types of changes that may be usefulfor your program to know. Events directly related to the hardware are thekeyboard and mouse events. Keyboard events are generated for each key whichis pressed (and released, if possible). The event contains the characterwhich caused the event. Mouse events are generated when a button on themouse is pressed or released, or when the mouse position moves. The eventcontains the buttons which are pressed, and the current position of the mouse.Other events are more subtle, and are based on non-physical changes, suchas having the mouse move into or out of specific windows.Events are generally tied to individual windows. Your program can enableor disable which kinds of events it wants for each window. Part of the dataassociated with an event is the window associated with the event. Forexample, if a key is pressed on the keyboard, the event for that key willindicate which window that key is for. You program can then act differentlyfor different windows. Events which you have not indicated an interest inare simply discarded.The keyboard and mouse events can propagate upwards through the window treeand be delivered to some parent window. This occurs if the window doesnot select for the event, but one of the parent windows does. Part of theinformation returned about these events is the window that accepted the event,and also the original window which caused the event. Therefore, your programcan determine which child window an event was for without having to selectfor the event for each child. Events other than keyboard and mouse eventsnever propagate.The window that keyboard events are delivered to depends on the currentmouse position or on the "input focus". The input focus is a way ofspecifying that keyboard events are to be delivered to a particular window,no matter where the mouse is currently pointing. Your program can changethe input focus as desired. If the input focus is set to the root window,then the keyboard events will be delivered to the window which containsthe mouse pointer (or one of its parents).Events are returned to your program as a structure containing the informationabout the event. This information is the event type, the window id whichthe event is associated with, and other event-specific data. Events arestored in a queue, and are delivered to your program one by one as requested.The order of the events is preserved. Your program can either simply askfor the next available event (waiting for one if none are yet available),or it can check to see if an event is available without waiting. Thedelivering of events only occurs when you request an event. So even thoughevents themselves are asychronous, the reading of them is synchronous.There are no "interrupts" for events, you must explicitly ask for them.The important thing about programming with events is that your programshould be written to run "upside-down". That is, you do not have a mainroutine which checks that the mouse has been moved, or the keyboard hasbeen typed on, or which window the mouse is in. Instead, your main routinejust waits for an event, and then dispatches on its type and which windowit is for. Generally, you must keep some state information to rememberwhat is happening in your program. For example, if the user wants to clickthe button in a window to indicate where some text should be inserted, thenyour program cannot simply detect the mouse click, and then wait for thetext to be typed. Instead, when the mouse is clicked, it should justremember the position of the mouse and set a flag to indicate that texttyping is allowed, When the keyboard event arrives, this saved informationthen enables you to draw the text at the correct location. Your programbasically becomes one large state machine.One obscure event is the exposure event. This is sent to your program whena window requires redrawing. Due to lack of memory space, the graphics serverdoes not attempt to save the data from the parts of windows which arecovered by other windows. Therefore, when the obscured parts of the windoware uncovered, your program must be told to redraw those parts. The exposureevent contains a rectangular area which requires drawing (which may in factbe larger than the area which was actually uncovered). Your program caneither just redraw that area, or if more convenient, redraw the whole window.The area to be redrawn has already been cleared to the window's backgroundcolor. When a window is mapped, an exposure event is sent for the window.Therefore, you should not explicitly draw into a window when it is firstcreated and mapped, but should instead just wait for the exposure event, andthen draw it. In this way, the code to draw the window only resides in oneplace in your program, and you prevent redundant drawing of the window.If you are drawing the complete window on all exposure events, then itmight be useful to use GrPeekEvent to examine the next event too. If itis also an exposure event for the same window, then you can read it by usingGrGetNextEvent, and thereby prevent redundant redrawing. Of course, tobe able to redraw the window, you may need to save extra data in order toregenerate the drawing commands. (Pixmaps are one way of doing this inthe future, but they are not currently implemented.)The following is a description of the various types of events which areavailable, and (in parenthesis) the typedef name for the structure thatreturns the event. Each event has a type field, which can be used todistinguish between the various events. For details on the other datawithin the structures, refer to graphics.h. The typedef GR_EVENT is aunion which contains all of the possible event structures.GR_EVENT_TYPE_NONE (GR_EVENT) This indicates that no event has occurred.GR_EVENT_TYPE_EXPOSURE (GR_EVENT_EXPOSURE) This is generated when a window needs redrawing because it is either newly mapped, or has been uncovered by another window. This returns the window id, and the x, y, width, and height of the area within the window which needs redrawing.GR_EVENT_TYPE_BUTTON_DOWN (GR_EVENT_BUTTON) This is generated when a button is pressed down on the mouse. This returns the window id which generated the event, the window id which actually contains the mouse, the current position of the mouse, the buttons which are currently down on the mouse, the buttons which were just pressed down, and the current modifier flags.GR_EVENT_TYPE_BUTTON_UP (GR_EVENT_BUTTON) This is generated when a button is released on the mouse. This returns data similarly to button down.GR_EVENT_TYPE_MOUSE_ENTER (GR_EVENT_GENERAL) This is generated when the mouse enters a window. This returns the window id which generated the event.GR_EVENT_TYPE_MOUSE_EXIT (GR_EVENT_GENERAL) This is generated when the mouse leaves a window. This returns the window id which generated the event.GR_EVENT_TYPE_MOUSE_MOTION (GR_EVENT_MOUSE) Mouse motion is generated for every motion of the mouse, and is used to track the entire history of the mouse. Mouse motion generates many events and causes lots of overhead. This returns data similarly to mouse enter.GR_EVENT_TYPE_MOUSE_POSITION (GR_EVENT_MOUSE) Mouse position ignores the history of the motion, and only reports the latest position of the mouse by only queuing the latest such event for any single client (good for rubber-banding). This returns data similarly to mouse enter.GR_EVENT_TYPE_KEY_DOWN (GR_EVENT_KEYSTROKE) This indicates that a key has been pressed on the keyboard. This returns the window id which generated the event, the window id which actually contains the pointer (if the pointer is outside of the event window, this will be the event window), the current position of the mouse, the current buttons on the mouse which are down, the current modifier flags, and the character which was typed.GR_EVENT_TYPE_KEY_UP (GR_EVENT_KEYSTROKE) This indicates that a key has been released on the keyboard. This event is not necessarily available, and should not be depended on. This returns data similarly to key down.GR_EVENT_TYPE_FOCUS_IN (GR_EVENT_GENERAL) This indicates that the input focus has just changed to this window. This returns the window id which got focus.GR_EVENT_TYPE_FOCUS_OUT (GR_EVENT_GENERAL) This indicates that the input focus has just left this window. This returns the window id which lost focus.To select for events, you use GrSelectEvents, and specify the window whichwants to receive the events, and also specify a mask indicating the eventsyou wish to receive. The mask is the logical OR of individual bit valuesrepresenting the event types. The mask names are the same as the eventnames, except that the "_TYPE_" string is replaced by "_MASK_". Forexample, the mask associated with the event GR_EVENT_TYPE_FOCUS_IN isGR_EVENT_MASK_FOCUS_IN.If you select for both button down and button up events, then the mousewill be implicitly "grabbed" when any button is pressed down in that window.This means that the mouse position and button down and up events will bedelivered only to that window, and the cursor shape won't change, even ifthe mouse leaves that window. The implicit grabbing ends after the lastbutton is released. While this grabbing occurs, the input focus is alsonot changed as the mouse is moved.MODIFIER AND MOUSE BUTTONSModifiers are the status of special keyboard shift-like keys. The stateof these keys can be read as up or down, and don't generate any charactersby themselves. These keys are for things like SHIFT, CTRL, and ALT.They are returned as bit values OR'd together in various events. Not allof these modifiers may be implemented. The GrGetScreenInfo function returnsthe modifiers that are implemented. The following modifiers are defined: GR_MODIFIER_SHIFT shift key is down GR_MODIFIER_CTRL ctrl key is down GR_MODIFIER_META meta (or ALT) key is down GR_MODIFIER_ANY any of the modifiers is downThe mouse button state are returned as bit values OR'd together in variousevents. Not all of these buttons may be implemented. The GrGetScreenInfofunction returns the buttons that are implemented. The following mousebuttons are defined: GR_BUTTON_1 button 1 is down (left) GR_BUTTON_2 button 2 is down (middle) GR_BUTTON_3 button 3 is down (right) GR_BUTTON_ANY any of the buttons is downBITMAPS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -