📄 microwindows_architecture.html
字号:
graphics engine, which calls the screen, mouse and keyboard drivers to interface with thehardware. User applications programs never all the core graphics engine routinesdirectly, but rather through the programmer API's, discussed in the next sections. The core engine routines are separated from the applications API's is for a variety ofreasons. The core routines will always reside on the server in a client/serverenvironment. Also, the core routines use internal text font and bitmap formats thatare designed for speed and may or may not be the same as the structures used in standardAPI's. In addition, the core routines always use pointers, never ID's, and can thenbe used together to implement more complex functions without always converting handles,etc.</p><p>In Microwindows, the core routines all begin as GdXXX() functions, and are concernedwith graphics output, not window management. In addition, all clipping and colorconversion is handled within this layer. The following files comprise the coremodules of Microwindows:</p><p> devdraw.c Core graphicsroutines for line, circle, polygon draw and fill, text and bitmap drawing, colorconversion</p><p> devclip.c Coreclipping routines. (devclip2.c is the new y-x-banding algorithm, devclip1.c an oldermethod)</p><p> devrgn.c New dynamically allocated routines for intersect/union/subtract/xor region creation.</p><p> devmouse.c Core routines for keepingthe mouse pointer updated or clipped from the screen.</p><p> devkbd.c Corekeyboard handling routines.</p><p> devpalX.c Linked instatic palettes for 1, 2, 4 and 8bpp palletized systems.</p><p>Section 2 following discusses the MicroGUI graphics engine routines in detail.</p><h3>1.4 Applications Programmer Interfaces</h3><p>Microwindows currently supports two different application programming interfaces. This set of routines handles client/server activity, window manager activities likedrawing title bars, close boxes, etc, as well as, of course, handling the programmer'srequests for graphics output. Both the API's run on top of the core graphics engineroutines and device drivers. </p><p>The basic model of any API on top of Microwindows is to hang in initialize the screen,keyboard and mouse drivers, then hang in a select() loop waiting for an event. Whenan event occurs, if it's a system event like keyboard or mouse activity, then thisinformation is passed to the user program converted to an expose event, paint message,etc. If it's a user requesting a graphics operation, then the parameters are decodedand passed to the appropriate GdXXX engine routine. Note that the concept of awindow versus raw graphics operations are handled at this API level. That is, theAPI defines the concepts of what a window is, what the coordinate systems are, etc, andthen the coordinates are all converted to "screen coordinates" and passed to thecore GdXXX engine routines to do the real work. This level also defines graphics ordisplay contexts and passes that information, including clipping information, to the coreengine routines.</p><p>Currently, the Microwindows API code is in win*.c, while the Nano-X API code is innanox/srv*.c.</p><h3>1.4.1 Microwindows API</h3><p>The Microwindows API tries to be compliant with the European ECMA APIW standard. Currently, there is support for most of the graphics drawing and clipping routines, aswell as automatic window title bar drawing and dragging windows for movement. TheMicrowindows API is message-based, and allows programs to be written without regard to theeventual window management policies implemented by the system. The Microwindows APIis not currently client/server, and will be discussed in more detail in section 4.</p><h3>1.4.2 Nano-X API</h3><p>The Nano-X API is modeled after the mini-x server written initially by David Bell,which was a reimplementation of X on the MINIX operating system. It loosely followsthe X Window System Xlib API, but the names all being with GrXXX() rather thanX...(). Currently, the Nano-X API is client/server, but does not have any provisionsfor automatic window dressings, title bars, or user window moves. There are severalgroups writing widget sets currently, which will provide such things. Unfortunately,the user programs must also then write only to a specific widget set API, rather thanusing the Nano-X API directly, which means that only the functionality provided by thewidget set will be upwardly available to the applications programmer. (Although thiscould be considerable, in the case that, say Gdk was ported.)</p><h3>2. Device-Independent Engine Features</h3><p>This section discusses in the capabilities and implementation of Microwindows' coregraphics engine in detail. It's purpose is both educational and to allow extendingan API by understanding how the engine works.</p><h3> 2.1 Graphics EngineFeatures and Implementation</h3><p>These routines concern themselves with drawing operations to off-screen or screensurfaces. Each routine starts with Gd... and is passed a pointer to the SCREENDEVICEstructure (PSD) as it's first parameter. The PSD parameter specifies the low leveldisplay details, like the x, y size of the device and the color model used by thehardware, for example. In addition, the actual routines to perform drawing arefunction pointers in this structure. All screen coordinates are of type COORD, andspecified in device coordinates, that is, offsets from the upper left corner of thescreen.</p><p>Colors are always specified as an RGB COLORVAL value into the graphics engine. They are then possibly converted to palette indices and sent to the display hardware asPIXELVAL values. In the case of 32bpp truecolor displays, no conversion isrequired. The color model will be discussed in detail below.</p><h3> 2.1.1 Regions</h3><p>Regions are used to describe arbitrary sets of pixels on the screen. A simple,square region of pixels can be described by a single rectangle. More complex sets ofpixels require more complex data structures. In Microwindows, regions are describedby an array of non-overlapping rectangles. Currently, there are two differentimplementations of regions in Microwindows, as I've been enhancing the capabilities inthis area. The original design used a single static array of CLIPRECTs to describecomplex regions. Any point within any rectangle in the array was considered to be inthe region. The array wasn't sorted in any particular order, but was alwaysguaranteed to contain non-overlapping rectangles. Another global variable,clipcount, specified the number of rectangles in the array. This original design hadno engine entry points for region management, the entire array was passed to the clippingfunctions, described below. </p><p>In the new design, any number of regions can be created, as the regions (CLIPREGION *)are stored as dynamically allocated arrays of rectangles. In this implementation,the non-overlapping rectangles are always kept in "y-x" sorted bands, such thateach band's y height is the same for all rectangles in the band. This means thatonly the x position and width of the rectangles in each band varied. Because ofthis, it is easier to create a set of functions for combining regions, since effectivelyonly a single dimension had to be compared for each region operation. The new regionhandling routines allow for creating and destroying regions, as well as combiningrectangles and regions with regions using Intersection, Union, Subtraction, and ExclusiveOr. This model allows regions to be implemented apart from the clipping routines,unlike the first version. Following are the new region routines:</p><p> GdAllocRegion - Create a region<br> GdDestroyRegion - Destroy a region<br> GdCopyRegion - Copy a region<br> GdUnionRectWithRegion - Union a rectangle witha region<br> GdIntersectRegion - Create a region from the intersection of two regions<br> GdSubtractRegion - Create a region from the difference of two regions<br> GdUnionRegion - Create a region from the union of two regions<br> GdXorRegion - Create a region from the XOR of two regions<br> </p><h3> 2.1.2 Clipping</h3><p>Clipping in Microwindows is closely tied to the region management code. At anypoint in time, the graphics engine has a single clipping region, that is a set ofrectangles, defined for any graphics operation. A point is drawn if it is"inside" any of the current set of clip rectangles. Two slightly modifiedversions of the clipping algorithm are supplied, devclip1.c for the original, staticrectangle array, and devclip2.c for the newer dynamically allocated array. A singleentry point GdSetClipRects, takes the passed region and specifies it's use for allsubsequent graphics operations. All the drawing routines then use the two additionalroutines to determine whether or not to draw. GdClipPoint takes an x,y point inscreen coordinates and returns TRUE if the point can be drawn, that is, the point iswithin one of the region rectangles. GdClipArea takes an upper left and lower rightpoint, and returns one of the following: CLIP_VISIBLE, if the specified area is completelywithin the region, CLIP_INVISIBLE, if the area is completely not in the region, whichmeans that no drawing should be performed, or CLIP_PARTIAL, if a part but not the wholearea is within the region. A typical graphics primitive will call the screen driverwith unmodified passed inputs if CLIP_VISIBLE is returned, or return if CLIP_INIVISIBLE isreturned. In the CLIP_PARTIAL case, the primitive must break up the original requestinto areas that are within the clip region before calling the screen driver. Thisslows down the operation considerably.</p><p>Because the clipping code is called constantly before drawing operations, Microwindowskeeps a global cache rectangle of the last rectangle checked with GdClipArea, for speedand also to allow the mid level to quickly calculate how partial drawing lengths.</p><h3> 2.1.3 Line Drawing</h3><p>Line drawing is the simplest of graphics operations. Microwindows supportsGdPoint to draw a point, and GdLine to draw a horizontal, vertical or diagonal (usingBresenham algorithm) line. Just before any call to the screen driver, a call toGdCheckCursor assures that the software cursor is removed prior to drawing. GdFixCursor restores the cursor if previously visible.</p><p>There is a tricky part to line drawing that had to be added during the support formultiple API's. This has to do with whether or not the last point in specified linesegment is drawn or not. There are two schools of thought on this, and to make itshort, Microwindows supports both of them. The last parameter to GdLine specifieswhether or not to draw the last point. The Microwindows API doesn't draw the lastpoint, but the Nano-X API does.</p><p>Most drawing functions, including line drawing draw using the "current"foreground color, specified using GdSetForeground. In addition a drawing mode,currently either MODE_SET or MODE_XOR can be specified using GdSetMode.</p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -