Primary X Programming 2

zhaozj2021-02-16  54

The organizational system of the window

When the windows are displayed on the X server, they usually sort in a certain organizational system - each window can have a sub-window, and each sub-window can have its own sub-window. Let us view some of the tissue systems to see how they affect, such as paintings and events.

Root window, parent window and sub-windows

There is a root window on every screen. The root window always occupies the entire screen size. This window cannot be destroyed, changed sizes or iconization. When an application creates some windows, it first creates at least one top window. After being mapped to the screen, this window becomes a direct sub-window of a root window. This window is informably what happened before being mapped to the screen, and then the window manager gets privileges to become a "father" of the new top window. This is usually used to add a window that will contain a new window and draw a frame, a title bar, a system menu, and more.

Once a top window (of course, it is actually not a top window, because the window manager has become its parent window) is created, the application can create its sub-window in it. A sub-window can only be displayed in its parent window - if you try to move it to the outside, the out part will cut off the border of the parent window. Any window can contain more than one sub-window, in which case these sub-windows will be placed on the application's internal stack. When a top window is opened - all of its sub-windows will also be opened as it.

The following example demonstrates how to open a sub-window in a given window.

Lets see how to create a child window inside a given window 'win'.

/ * This Variable Will Store The Handle of The Newly Created Child WINDOW. * /

WINDOW CHILD_WIN;

/ * THESE VARIABLES WILL STORE The Window's Width and Height. * /

INT Child_WIN_WIDTH = 50;

INT Child_WIN_HEIGHT = 30;

/ * Sests Will Store the window's location. * /

/ * position of the child window is top-left corner of the * /

/ * Parent window. - 0, 0. * /

INT child_win_x = 0;

INT child_win_y = 0;

/ * CREATE The window, as specified earlier. * /

Child_win = XcreatesImpleWindow (Display,

Win,

Child_win_x, child_win_y,

Child_win_width, child_win_height,

Child_win_border_width,

Blackpixel (Display, Screen_Num),

WhitePixel (Display, Screen_Num);

Event delivery

Previous we have discussed event delivery - if a window received an event it not processed - it sent the event to its parent window. If that parent window does not process the event - the parent window sent the event to its parent window, next to this class. This behavior is useless to a simple XLIB program, but it is useful for the higher level of abstract level. These abstract levels higher draw libraries typically contact events of a particular window. In this case, it is very useful to send events to a specific window and use the appropriate function.

Interact with window manager

After we look at how to create and draw a window, let's take a look at how our window interacts with their environment - the entire screen and other windows. First, our program needs to interact with the window manager. Window Manager is responsible for decorating a drawn window (for example, adding a frame, a iconized button, a system menu, a title bar), and draw icons when the window is iconized. It also manages the window arrangement in the screen and other manageable tasks. We need to give it a variety of tips to treat our window in the way we need. Window attribute

Many parameters with the window manager are passed through data called "Properties". The X server puts these properties on a variety of windows while storeting them into a format (remember, one X client) that can be read by a system of various architectures (remember). The property can be various types, numbers, strings, and more. Most window manager prompt function uses text properties. A function called XStringListTotExtProperty () can convert the string of the C language to the X text property, and the resulting result can be passed to each color XLIB function. The following is an example:

/ * This Variable Will Store the newly created property. * /

XtextProperty WINDOW_TITLE_PROPERTY;

/ * This is the string to be translated into a property. * /

Char * window_title = "Hello, World";

/ * Translate the given string Into an x ​​property. * /

INT rc = xstringlisttotextproperty (& window_title,

1,

& window_title_property;

/ * check the success of the translation. * /

IF (rc == 0) {

FPRINTF (stderr, "xstringlisttotextproperty - out of memory / n");

Exit (1);

}

Function XStringListTTotextProperty () Receives a C-string matrix (only one in our example) and a pointer to the xtextproperty variable as a parameter, the attributes in the merge C strings turn the value to the xtextproperty variable. When it successfully returned a non-0 value, returned 0 (for example, without enough memory to complete the operation).

Set the window name and icon name

The first thing we need to do is to set the name to our window. Use the function xsetwmname (). Window Manager may display this name on the window title bar or on the taskbar. This function accepts 3 parameters: a pointer to the display, a window handle, and a xtextproperty variable containing the name we set. Here is how we do:

/ * Assume That window_title_property is out textproperty, and is * /

/ * Defined to Contain The Desired Window Title. * /

XSETWMNAME (Display, Win, & WINDOW_TITLE_PROPERTY);

In order to set the icon name of our window, we will use the function xsewmiconname () in the same way.

/ * THIS TIME We Assume That icon_name_property is an inTILALIZED * /

/ * XTextProperty variable containing the desired icon name. * /

XSetWmiconName (Display, Win, & icon_Name_Property);

Set a satisfactory window size

In various cases, we want the window manager to know the window size we specified and only allow the user to change the window size under our qualification. For example, a terminal window (like xterm), we always ask our window to include all rows and columns, so we can't truncate our display from the middle. In other cases, we don't want our window to be changed (like the vast majority of dialog windows), and so on. We can rely on this dimensional information of the window manager, although it may be simply ignored. We first need to create a data structure to include this information, fill the necessary data, and then use the function xsetwmnormalhints (). Here's how to do:

/ * Pointer to the size hints structure. * /

Xsizehints * win_size_hints = xallocsizehints ();

IF (! WIN_SIZE_HINTS) {

FPRINTF (stderr, "xallocsizehints - out of memory / n");

Exit (1);

}

/ * Initialize the structure appropriately. * /

/ * First, Specify Which size hints we want to fill in. * /

/ * in Our Case - Setting the minimal size. * /

Win_SIZE_HINTS-> FLAGS = Psize | Pminsize;

/ * Next, Specify THE DESIRED LIMITS. * /

/ * in Our Case - Make The Window's Size At Least 300x200 Pixels. * /

/ * And make it its initial size 400x250. * /

Win_SIZE_HINTS-> min_width = 300;

Win_SIZE_HINTS-> min_HEight = 200;

Win_SIZE_HINTS-> BASE_WIDTH = 400;

Win_SIZE_HINTS-> BASE_HEIGHT = 250;

/ * Pass the size hints to the window manager. * /

XSetWmnormalhints (Display, Win, Win_SIZE_HINTS);

/ * Finally, we can free the size hints structure. * /

Xfree (win_size_hints);

Please check your manual to get the full information of the size prompt.

Set various window manager prompts

You can also set up a number of other window manager prompts using a function xsetwmhints (). This function uses an XWMHINTS structure to pass parameters to the window manager. Here is an example:

/ * Pointer to the wm hints structure. * /

XWMHINTS * WIN_HINTS = xallocwmhints ();

IF (! win_hints) {

FPRINTF (stderr, "xallocwmhints - out of memory / n");

Exit (1);

/ * Initialize the structure appropriately. * /

/ * First, Specify Which Hints WE Want to Fill In. * /

/ * IN OUR CASE - Setting The State Hint As Well as the icon position hint. * /

Win_HINTS-> FLAGS = StateHint | iconpositionHint;

/ * Next, Specify the desired hints data. * /

/ * in out - make the window's initial state be iconized, * /

/ * and set the icon position to the top-left part of the screen. * /

Win_HINTS-> Initial_State = iconicState;

Win_HINTS-> ICON_X = 0;

Win_HINTS-> ICON_Y = 0;

/ * Pass the hints to the window manager. * /

XSetWmhints (Display, Win, Win_HINTS);

/ * Finally, We can free the wm hints structure. * /

Xfree (win_hints);

Please refer to the manual for more information on all options.

Set an icon for a program

When the user is standardized, in order to make the window manager set an icon for our program, we use the functions mentioned above XSetWmhints. However, first we need to create a pixel map that contains icon data. X The server uses a pixel map to operate the picture, which will be described in detail later. Here, we just show you how to set icons for your program. We assume that you have already got an icon file in x bitmap. The tutorial provides an icon file "icon.bmp" for convenience, below:

/ * incrude the definition of the bitmap in our program. * /

#include "icon.bmp";

/ * Pointer to the wm hints structure. * /

XWMHINTS * WIN_HINTS;

/ * Load The Given Bitmap Data and create an x ​​pixmap containing it. * /

Pixmap icon_pixmap = xcreatebitmapfromdata (Display,

Win,

Icon_bitmap_bits,

Icon_bitmap_width,

icon_bitmap_height);

IF (! iCon_pixmap) {

FPRINTF (stderr, "xcreatebitmapfromData - error creating pixmap / n");

Exit (1);

}

/ * Allocate a wm hints structure. * /

Win_HINTS = xallocwmhints ();

IF (! win_hints) {

FPRINTF (stderr, "xallocwmhints - out of memory / n");

Exit (1);

}

/ * Initialize the structure appropriately. * /

/ * First, Specify Which size hints we want to fill in. * /

/ * IN OUR CASE - Setting the icon's pixmap. * / win_hints-> flags = iconpixmaphint;

/ * Next, Specify the desired hints data. * /

/ * IN OUR CASE - Supply the icon's design pixmap. * /

Win_HINTS-> icon_pixmap = icon_pixmap;

/ * Pass the hints to the window manager. * /

XSetWmhints (Display, Win, Win_HINTS);

/ * Finally, We can free the wm hints structure. * /

Xfree (win_hints);

You can use programs such as "XPaint" to create files that use the x bitmap format.

We provide file simple-wm-hints.c to summarize this section, this program includes creating a window, setting the window manager prompt to display on top, and a simple event loop. It allows users to adjust parameters to view how prompt affects the behavior of programs. This can help you understand the portability of the X program.

Simple window operation

For our window, we can do more things. For example, changing their dimensions, open or close them, iconizes them. XLIB provides a series of functions to complete the functions mentioned above.

Mapping and release a window mapping

First we make a pair of operations to the window to map it to the screen and release it. The operation of mapping a window will display a window on the screen, as we see in the simple window program example. The release map will remove the window from the screen (although it is still in the X server as a logical node). This can provide an effect of generating a window hidden (mapping release) and then display (mapping). For example, there is a dialog in our program, we don't need to recreate a window every time you need it, we just create once in the state of the mapping, simply map it to the screen when the user needs it. Go up. This is more than every time you create it and destroy it. Of course, this requires more memory in the client and server.

You should still remember that the mapping operation is using the function xmapWindow (). The mapping release operation is how to use the function xunmapWindow (), how is the following:

/ * Make the window actually Appear on the screen. * /

XMapWindow (Display, Win);

/ * Make the window hidden. * /

XunmapWindow (Display, Win);

Unless the entire window is overwritten by other windows, an exposed event will be sent to the application after the mapping operation.

Moving a window on the screen

Another operation we want to do is moving the window in the screen. This action can be done using the function xmoveWindow (). It accepts the new coordinates of the window, the method and function XcreateSimpleWindow () used by the window. A picture of the call:

/ * Move the window to coordinates x = 400 and y = 100. * /

XMOVEWINDOW (Display, Win, 400, 100);

Note When the window moves, the part of the window may be blocked or re-exposed so that we may receive exposed events.

Change window size

The next thing we have to do is to change the size of a window. Use functions XResizeWindow () can complete this action:

/ * Resize the window to width = 200 and height = 300 Pixels. * / XresizeWindow (Display, Win, 200, 300);

We can merge and change the size to operate as an operation, use the function xMoveresizeWindow ():

/ * move the window to location x = 20 y = 30, and change its size * /

/ * to width = 100 and height = 150 pixels. * /

XMoveresizeWindow (Display, WIN, 20, 30, 100, 150);

Change the stack order of the window - improvement and decrease

We have changed many attributes of a separate window so far. Next we will look at the properties between the windows. One of them is their stack properties. That is, how the window is arranged on the screen. The front window We said it is on the top of the stack, the last window we said it is in the bottom of the stack. The following demonstrates how we change the stack order of the window:

/ * Move the given window to the top of the stack. * /

XraiseWindow (Display, Win1);

/ * Move the given window to the bottom of the stack. * /

XLowerWindow (Display, Win1);

Icon and restore a window

Here we will explain the last operation of how to transform a window into an icon status and restore it. Use the function XiconifyWindow () to transform a window into an icon status, use the function xmapWindow () to restore it. In order to help understand why the icon function does not have a corresponding counter function, we must understand that when a window is iconized, the actually happens is that the window is released, and its chart is mapped. As a result, if you want to make which window appears, we only need to make a simple mapping it will. The icon is actually another window, but it has a very strong relationship with our windows. The following demonstrates how to mark a window and restore it:

/ * iconify our window. make it it it ippear on the same * /

/ * Screen As Our Window (Assuming We create Our window on the * /

/ * Default screen). * /

XiconifyWindow (Display, Win, Defaultscreen);

/ * de-iconify our window. The icon window will be automatic * /

/ * unmapped by this Operation. * /

XMapWindow (Display, Win);

Get information on a window

As you can set a lot of properties for the window, we can also ask the X server to provide values ​​for these properties. For example, we can check what location in the screen now, current size, is mapped, and so on. Functions XGetWindowAttributes () can help us get those information:

/ * this variable will contact the attributes of the window. * /

XWindowAttributes win_attr;

/ * query the window's attributes. * /

Status rc = XGetWindowAttributes (Display, Win, & WIN_ATTR); Structural XWindOWAttributes contains many data domains, below is part of it:

INT X, Y;

The location of the window is relative to its parent window.

Int width, Height;

Wide and high (unit, pixel) of the window.

Int border_width

Window border width

WINDOW ROOT;

Root window, that is, our window is displayed in that window.

Some questions this function is that it returns to the location relative to the parent window. This does not make sense to other windows, such as XMOVEWindow. In order to solve this problem, we need to use two steps. First, we find the ID of the parent window of the window. Then we use it to determine the coordinates of the window relative to the screen. We use two functions that have not been introduced in front to complete this calculation, xQueryTree () and XTranslateCoordinates (). The functions of these two functions beyond our needs, so we only pay attention to what we need:

/ * THESE VARIABLES WILL EVENTUALLY HOLD The Translated Coordinates. * /

INT screen_x, screen_y;

/ * this variable is here smeply because it's needed by the * /

/ * XTranslateCoordinates Function Below. For ITS Purpose, See The * /

/ * manual page. * /

WINDOW CHILD_WIN;

/ * this variable will store the id of the parent window of ot window. * /

WINDOW PARENT_WIN;

/ * this variable will store the id of the root window of the screen * /

/ * OUR WINDOW is Mapped on. * /

WINDOW ROOT_WIN;

/ * this variable will store an array of ids of the child windows of * /

/ * OUR WINDOW. * /

WINDOW * Child_Windows;

/ * And this one will store the number of child windows our window HAS. * /

INT NUM_CHILD_WINDOWS;

/ * finally, make the query for the above value. * /

XQueryTree (Display, Win,

& root_win,

& parent_win,

& child_windows, & num_child_windows;

/ * WE NEED TO Free The List of child IDs, as it was dynamical allocated * /

/ * by the xquerytree function. * /

Xfree (Child_Windows); / * Next, We make the coordinates translation, from the coordinates system * /

/ * of the parent window, to the coordinates system of the root window, * /

/ * Which happens to be the same as what of the screen, since the root * /

/ * WINDOW ALWAYS Spans the entire screen size. * /

/ * the 'x' and 'y' Values ​​Are Those Previously Returned by the * /

/ * XGetwindowAttributes function. * /

XtranslateCoordinates (Display, Parent_Win, Root_WIN,

Win_ATTR.X, WIN_ATTR.Y, & Screen_x, & Screen_Y,

& child_win);

/ * at this point, screen_x and screen_y contain the location of out original * /

/ * WINDOW, Using Screen Coordinates. * /

You can see that Xlib sometimes makes us handle problems.

The above content can be referred to the example of Window-Operations.c program.

Use the color to draw rainbow to so far, our drawing operations only use black and white two colors. Now let's take a look at how to use rich colors to draw.

Color mapping

First, it is not complete enough color. The screen controller can only support limited colors. Therefore, an application cannot just require the color "light purple", I hope that this color can be supported. Each application assigns its own color, if all 16 or 256 color entrances are already in use, the next color assignment will fail.

As a result, "a color mapping" is described. A color mapping is a table that is the same as the number of colors that can support simultaneously with the screen controller. The nodes in each table contain a RGB (red, green and blue) for each color. When an application wants to draw on the screen, it does not specify what color used, but specifies the node in the mapping table, so the value of a node in the chart will change the color of the program.

In order to let the programmer use the color he want to draw, the color map allocation function is provided. You can request allocated a color mapping node to correspond to a RGB value, and then the index value of a node is returned to you. This will fail if it is full. You can follow the colors to meet your needs. This means that a similar color will be drawn to the screen.

On the modern display used in today's X servers, it can generally support millions of colors, which may seem stupid, but remember that there are still many old display cards and displays being used. With color mapping, you can use them without considering the server's screen hardware details. On a single support for millions of monitors, any color allocation request should be successful. A similar color may be used in a display that supports a limited color, which may not look good, but your program can still work.

Assign and release color mapping

When you use xlib to draw, you can select the standard color map of the screen, or assign a new color map for your window. In the latter case, each mouse is moved on your window, you will replace the default screen mapping, and then you will see the screen of the other window color changes. In fact, this is the same as you run x applications using the "-Install" option. The system defines the macro defaultColormap to get the standard color mapping of the screen:

ColorMap Screen_Colormap = DefaultColormap (Display, Defaultscreen (Display);

The above call will return the default color mapping of the first screen (more reminders, an X server can support several different screens at the same time, each screen can have its own resources).

Another option, assign a color map, like this:

/ * First, Find The Default Visual for Our Screen. * /

Visual * default_visual = defaultvisual (Display, Defaultscreen (Display);

/ * This Creates A New Color Map. The Number of Color Entries in this map * /

/ * Is determined by the number of colors supported on the given screen. * /

ColorMap my_colormap = XcreateColormap (Display,

Win,

DEFAULT_VISUAL,

Allocnone);

Note that the Window parameter is used to allow the X server to assign color mappings for the specified screen. We can then use allocated colors to map any of the windows in the same screen.

Assign and release color node

Once we gain access to color maps, we can start allocating colors. Use the function xallocnamecolor () and xallocclor () to complete this work. First function xallocnamecolor () get the name of the color (eg, "Red", "Blue", "Brown", etc.) and then gets the actual similar color that can be used. Function Xalloccolor () Access RGB color. Both functions use the XColor structure, which have some of the following data fields:

Unsigned long pixel

Color map node index.

Unsigned Short Red

Red portion of the RGB color value.

Unsigned Short Green

RGB color value of the green part.

Unsigned Short Blue

RGB color value of the blue portion.

The following example:

/ * THIS STRUCTURE WILL Store The Color Data Actually Allocated for US. * /

Xcolor System_Color_1, System_Color_2;

/ * This Structure Will Store The Exact RGB Values ​​of The named color. * /

/ * IT Might Be Different from What Was Actually Allocated. * /

Xcolor exact_color;

/ * Allocate a "red" color map entry. * /

Status rc = xallocnamedcolor (Display,

Screen_colormap,

"red",

& systems_color_1, & exact_color;

/ * make Sure the allocation succeed. * /

IF (rc == 0) {

FPRINTF (stderr,

"XallocnamedColor - Allocation of 'Red' Color Failed./N");

}

Else {

Printf ("Color Entry for 'Red' - Allocated AS (% D,% D,% D) in RGB VALUES./N",

System_color_1.red, system_color_1.green, system_color_1.blue;

}

/ * Allocate a Color with Values ​​(30000, 1000, 0) in RGB. * /

System_color_2.red = 30000;

System_color_2.green = 10000;

System_color_2.blue = 0;

Status rc = xalloccolor (Display,

Screen_colormap,

& system_color_2);

/ * make Sure the allocation succeed. * /

IF (rc == 0) {

FPRINTF (stderr,

"Xalloccolor - Allocation of (30000, 10000, 0) Color Failed./N");

}

Else {

/ * Do Something with the allocated color ... * /

.

.

}

Use an eye-drawn

After we allocate the desired color, we can use them to draw text or graphics. To achieve the goal, we need to set the colors that the colors given to some GC (graphics context) as the foreground color and background colors, and then use the set GC to draw. Use the function XsetForeground () and XSetBackground (), as follows:

/ * Use the previously defined colors as the foreground and background * /

/ * Colors for Drawing Using The Given GC. Assume my_gc is a handle to * /

/ * a previously allocated gc. * /

XsetForeground (Display, My_GC, Screen_Color_1.pixel);

XsetForeground (Display, My_GC, Screen_Color_2.pixel);

As you can see, this is an example of use. Actual drawing work uses the drawing function we have previously introduced. Note that in order to complete the drawing work in a variety of colors, we can use two methods. We can change the values ​​of the GC before calling the drawing function, or use the GC representative of different colors. Which method is used by yourself according to the situation. Note that the use of multiple GC reduces the extra resources of the X server, but this can make your code more compact.

As an example of using color, please check the example of Color-Drawing.c. This is a copy of the program Simple-Drawing.c, and we just add a color part in it.

X Bitmaps and Pixmaps

One thing that is known as multimedia procedures is to display pictures. In the world of x, use Bitmaps and Pixmaps to implement this feature. We have already used them in the introduction of the icon for our program. Let us now study them and see how it is drawn in a window. One thing to note before entering, XLIB cannot handle many currently popular image formats, such as GIF, JPEG, or TIFF. These are left to the application (or some graphics processing libraries) to convert X-bitmaps and x pixmaps that are acceptable to X servers.

What is a x bitmap? And X Pixmap?

An Xbitmap is a two-color graphic format with a X window system defined. When saved in a file, Bitmap data looks like a C source program. It includes a variable that defines a wide picture, an optional a matrix (size = width * height of the matrix), and an optional hotspot location (will explain the part of the cursor behind).

A X Pixmap is a format that saves an image in memory in memory. This format can store black and white pictures (such as x bitmaps) or save pictures with colors. This is actually the only picture format that the X protocol can support, and any picture is to be converted into this format if you want to be displayed on the screen.

In fact, a X Pixmap should be considered a window that is not drawn to the screen. Many graphics operations on the window can also work in X Pixmap, but only use the X Pixmap ID instead of the window ID. In fact, if you check the manual, you will find that all these functions are accepting a "Candid" parameter rather than a window parameter. Because both types are convicted, they can be used, for example, XDrawarc (), XDrawText (), and more.

Read a Bitmap from a file

In the program of the icon, we have seen how to load a bitmap into memory from a file. The method we use in front is to use the C pre-encoder "#include". Let's see how you read it directly from the file.

/ * this variable will contact the id of the newly created pixmap. * /

Pixmap bitmap;

/ * THESE VARIABLES WILL Contain The Dimensions of the loaded bitmap. * /

Unsigned int bitmap_width, bitmap_height;

/ * THESE VARIABLES WILL Contain The location of the hot-spot of the * /

/ * loaded bitmap. * /

INT Hotspot_x, Hotspot_Y;

/ * this variable will contain the id of the root window of the screen * /

/ * for which we want the pixmap to be created. * /

WINDOW ROOT_WIN = DefaultRootwindow (Display);

/ * Load the bitmap found in the file "icon.bmp", Create a Pixmap * /

/ * Containing ITS Data in Server, and Put ITS ID in the 'Bitmap' * /

/ * variable. * / int RC = xreadbitmapfile (Display, root_win,

"icon.bmp",

& bitmap_width, & bitmap_height,

& bitmap,

& hotspot_x, & hotspot_y);

/ * Check for failure or success. * /

Switch (rc) {

Case Bitmapopenfailed:

FPRINTF (stderr, "xreadbitmapfile - could not open file 'icon.bmp' ./ n");

Break;

Case BitmapFileInvalid:

FPRINTF (stderr,

"XreadBitmapFile - File '% s' Doesn't Contain A Valid Bitmap./N",

"icon.bmp");

Break;

Case BitmapNomeMory:

FPRINTF (stderr, "xreadbitmapfile - not enough memory./n);

Break;

Case Bitmapsuccess:

/ * Bitmap loaded successfully - do something with it ... * /

.

.

Break;

}

Note that the given BitMap parameter "root_win" does not afford - the Bitmap read is not connected to this window. This window handle is only used to indicate the screen used by Bitmap. This is very important, Bitmap must support the same number of colors as the screen, so that it can play a role.

Draw graphics in one window

Once we get the handle of Pixmap from Bitmap, we can use the function XcopyPlane () to draw it into the window. This function can help us specify what (a window, even another Pixmap) can draw this Pixmap.

/ * Draw the previously Loaded Bitmap on The Given WINDOW, ATLOCATION * /

/ * 'x = 100, y = 50' in That window. we want to copy the whole bitmap, so * /

/ * WE Specify Location 'x = 0, y = 0' of the bitmap to start the copy from, * /

/ * And the full size of the bitmap, to specify how much ip. * /

XcopyPlane (Display, Bitmap, Win, GC,

0, 0,

Bitmap_width, Bitmap_Height,

100, 50,

1);

As you can see, we can copy the formulated rectangular area instead of the entire PIXMAP. It is also important to note that the last parameter of the function XcopyPlane ("1" of that end) is. This parameter specifies that the plane is copied from the source. For Bitmaps, we usually only copy the plane 1. When we discuss the color depth, we can do this.

Create a PIXMAP

Sometimes we need to create a Pixmap without an initialization so that we can draw next to it. This is very useful for image drawing programs. In addition, this is also very useful to read image data in various formats. / * This Variable Will Store the Handle of the newly created pixmap. * /

Pixmap pixmap;

/ * this variable will contain the id of the root window of the screen * /

/ * for which we want the pixmap to be created. * /

WINDOW ROOT_WIN = DefaultRootwindow (Display);

/ * this variable will contact the color defth of the pixmap to create. * /

/ * this 'Depth' Specifies the Number of Bits Used to Repesent A Color * /

/ * index in the color map. The number of colors is 2 to the power of * /

/ * this depth. * /

INT depth = defaultDepth (Display, Defaultscreen (Display);

/ * CREATE A NEW PIXMAP, WITH A WIDTH OF 30 PIXELS, AND Height of 40 Pixels. * /

Pixmap = XcreatePixmap (Display, root_win, 30, 40, defth);

/ * Just for Fun, Draw A Pixel in the Middle of this Pixmap. * /

XDrawPoint (Display, Pixmap, GC, 15, 20);

Draw a Pixmap in a window

After we get a Pixmap handle, we can use it to draw in the window, use the function Xcopyarea ().

/ * Draw the previously Loaded Bitmap on The Given WINDOW, ATLOCATION * /

/ * 'x = 100, y = 50' in That window. we want to copy the whole bitmap, so * /

/ * WE Specify Location 'x = 0, y = 0' of the bitmap to start the copy from, * /

/ * And the full size of the bitmap, to specify how much ip. * /

XcopyPlane (Display, Bitmap, Win, GC,

0, 0,

Bitmap_width, Bitmap_Height,

100, 50,

1);

As you can see, we can copy the specified rectangular area instead of the entire PIXMAP.

Another need to be emphasized is - can create different depth Pixmap on the same screen. When we perform copy jobs (copy Pixmap on one window), we should ensure that the source and goals are used in the same depth. If the depth of the two is different, the operation will fail. Unless we use the function XcopyPlane () as used earlier () to complete this action. In such a case, we copy the specified plane to the window, actually specify each of the copied color bits. This operation can make many special effects, but this is beyond the scope of this article. Release a PIXMAP

Finally, when we completed the operation of a Pixmap, we should release the resources it occupied. Use the function xfreepixmap ().

/ * free the pixmap with the given id. * /

XfreePixMap (Display, Pixmap);

After release a Pixmap - we absolutely no longer access it.

As a summary of this chapter, look at the program draw-pixmap.c.

Change mouse cursor

We often see programs that change the mouse spectros (often referred to as an X cursor). For example, a program that is working in a bury will often turn the cursor to an hourglass, prompting the user to wait to handle new requests. If there is such a prompt method, the user will think that the program has been stuck. Let's take a look at how to change the mouse cursor for our window.

Create and destroy mouse cursor

The system provides two ways to create cursors. One is the use of system predefined shapes, supported by XLIB. The other is that the program provides a bitmap to display.

When using the previous method, we use a special font name "Cursor" and the corresponding function XCREATEFONTCURSOR (). This function accepts a shape indication and returns a handle that represents the generated cursor. file

List the type of cursor supported by the system, the following is one of them:

XC_ARROW

The usual cursor displayed by the X server.

XC_Pencil

A pen's cursor.

XC_Watch

A styling hourglass

It is very simple to use these symbols to create cursors:

#include / * defines XC_Watch, etc. * /

/ * This variable will hold the handle of the newly created cursor. * /

Cursor Watch_Cursor;

/ * CREATE A Sand Watch Cursor. * /

Watch_cursor = XcreateFontCursor (Display, Xc_Watch);

Another method of creating a mouse cursor is used in a pair of PIXMAPS. A PIXMAP defines the shape of the cursor and the other is a mask to specify what the previous one is displayed. Other content will become transparent. Create a cursor usage function XcreatePixMapCursor (). In the example below, we will use "icon.bmp" to create cursors. We will assume that it has been loaded into the memory and has been converted into Pixmap, and the returned handle is saved to the "Bitmap" variable. We hope it is completely transparent. That is, only the portion of the black color will be indeed drawn on the screen. In order to achieve this, we will use it to make cursor Pixmap and do masks Pixmap. I hope you can understand why ...

/ * This variable will hold the handle of the newly created cursor. * /

Cursor icon_cursor;

/ * first, we need to define foreground and background colors for the cursor. * /

Xcolor Cursor_fg, CURSOR_BG;

/ * Access the default color map of ou screen. * /

ColorMap Screen_Colormap = DefaultColormap (Display, Defaultscreen (Display);

/ * Allocate Black and while colors. * /

Status rc = xallocnamedcolor (Display,

Screen_colormap,

"Black",

& cursor_fg,

& CURSOR_FG);

IF (rc == 0) {

FPRINTF (stderr, "xallocnamedcolor - cannot allocate 'black" ?? !! ?? / n ");

Exit (1);

}

Status rc = xallocnamedcolor (Display,

Screen_colormap,

"White",

& cursor_bg,

& cursor_bg);

IF (rc == 0) {

FPRINTF (stderr, "xallocnamedcolor - cannot allocate 'White' ?? !! ?? / n");

Exit (1);

}

/ * finally, generate the cursor. make the 'hot spot' be close to the * /

/ * Top-left corner of the cursor - location (x = 5, y = 4). * /

icon_cursor = XcreatePixmapcursor (Display, Bitmap, Bitmap,

& cursor_fg, & cursor_bg,

5, 4);

What needs to be described above is the parameter "Hot Spot". When we define a cursor, we need to indicate which pixel in the cursor is used to generate a variety of mouse events. Typically, we specify a point that looks like "Hot Spot" based on habits. For example, an arrow shape cursor, we will choose the arrow pointed to "Hot Spot".

Finally, we don't need to use the cursor again, we can use the function xfreecursor () to release its resources:

Xfreecursor (Display, icon_cursor);

Set the mouse cursor of a window

After we created the cursor, we can tell the X server to put it on any window. Use the function xdefinecursor (), the X server changes the shape of the cursor when each cursor is moved into the specified window. We can use the function Xundefincursor () to revoke the specified you just. This way, the mouse will use the default cursor when the mouse is moved into the specified window.

/ * attach the icon cursor to company window. * /

XDefineCursor (Display, Win, Icon_Cursor);

/ * DETACH The icon cursor from ou window. * /

Xundefinecursor (Display, Win);

As an example, check the program cursor.c.

转载请注明原文地址:https://www.9cbs.com/read-26980.html

New Post(0)