17 KiB
---+!!17 Developing Customized MiniGUI-Processes Server Program
mginit is the server program of MiniGUI-Processes. This program prepares
shared resource for client programs and manages windows created by clients. We
explain how to write a customized MiniGUI-Processes server program according
to the project requirement in this chapter. We first use program mginit of
mg-samples as an example to analyze the basic constitution of mginit
program.
mginit in mg-samples
mginit in mg-samples is relatively simple, which is mainly responsible for
following tasks:
- Initializing itself as the server of
MiniGUI-Processes; - Showing two dialog boxes displaying copyright information;
- Reading mginit.rc configuration file and creating a task bar;
- Starting up the default startup program specified by mginit.rc file;
- Maintaining information of
MiniGUI-Processeslayers and switching between layers in the taskbar window procedure.
Now we analyze the implementation of mginit in mg-samples.
Initializing Itself as the Server of MiniGUI-Processes
The following code is located in function MiniGUIMain:
First, this function initializes variables OnNewDelClient and
OnChangeLayer, which are the global variables owned by the server program.
After this, the function calls ServerStartup to start the server function of
mginit. ServerStartup function will create listening socket, prepare to
accept the connection requests from clients. So far the server initialization
has finished. Let’s analyze the above process in details.
1. Listen events coming from clients and layers
The global variables OnNewDelClient and OnChangeLayer are only available
for MiniGUI-Processes server program. They are two function pointer
variables. When a client connects to mginit or drops the socket connection
with mginit, and if the variable of OnNewDelClient has been set, MiniGUI will
call the function pointed to by this variable. In minigui/minigui.h, the
declaration of this function prototype is as follows:
The first argument indicates the operation that will be processed. When the
parameter gets LCO_NEW_CLIENT, it represents that there is new client being
connecting to the server; if parameter is LCO_DEL_CLIENT, it means that a
client is dropping the connection. The second argument cli is the client
identifier; it is an integer.
When the layer of MiniGUI-Processes changes, for example, a new client joins
to a certain layer, and if the variable of OnChangeLayer has been set,
MiniGUI will call the function pointed to by this variable. In
minigui/minigui.h, the declaration of the prototype of this function is as
follows:
The first argument represents the event type:
LCO_NEW_LAYER:A new layer has been created;LCO_DEL_LAYER:A layer has been deleted;LCO_JOIN_CLIENT:A client joined to a certain layer;LCO_REMOVE_CLIENT:A certain client is deleted from the layer it lies;LCO_TOPMOST_CHANGED:The top-most layer changes, that is, the switch of layer occurred;
The second argument is the pointer to the relevant layer. The third argument is the pointer to the relevant client.
The global variable OnZNodeOperation only available for MiniGUI-Processes
server program since MiniGUI V2.0.4/V1.6.10. It is also function pointer
variable. When the znode changes in MiniGUI-Processes and the variable of
OnZNodeOperation has been set, MiniGUI will call the function pointed to by
this variable. In minigui/minigui.h, the declaration of this function prototype
is as follows:
The first argument represents the event type:
ZNOP_ALLOCATE:The z-node has been created;ZNOP_FREE:The z-node has been destroyed;ZNOP_MOVE2TOP:The z-node has been moved to be the topmost one;ZNOP_SHOW:The z-node has been shown;ZNOP_HIDE:The z-node has been hidden;ZNOP_MOVEWIN:The z-node has been moved or its size has changed;ZNOP_SETACTIVE:The z-node has been set to be the active one;ZNOP_ENABLEWINDOW:The z-node is disabled or enabled;ZNOP_STARTDRAG:Start to drag the z-node;ZNOP_CANCELDRAG:Cancel to drag the z-node;ZNOP_CHANGECAPTION:The caption of the z-node has changed.
The second argument cli is the client identifier; it is an integer. The third
argument idx_znode is the znode index.
The global variables OnLockClientReq, OnTrylockClientReq, and
OnUnlockClientReq are available for MiniGUI-Processes client program. They
are three function pointer variables. They can avoid thread deadlock problem in
the same process. In minigui/minigui.h, the declaration of this function
prototype is as follows:
Once having client identifier or layer pointer and client pointer, mginit can
easily access the internal data structure of MiniGUI library, and so can get
some system information. For doing this, MiniGUI defines the following global
variables:
mgClients:AnMG_Clientstructure pointer. It points to anMG_Clientstructure array including all clients’ information. You can use the client identifier to access it.mgTopmostLayer:AnMG_Layerstructure pointer, pointing to the current top-most layer.mgLayers:AnMG_Layerstructure pointer, pointing to the head of a linked-list of all layers in the system.
mginit program can visit these data structure at any time to get the current
client and the current layer information. Regarding members of MG_Client and
MG_Layer structures can refer to MiniGUI API Reference.
mginit in mg-samples defines two functions to handle above events, and also
sets two global variables mentioned above.
The first function is on_new_del_client, which does not have material work,
but just simply prints the name of the client coming or dropping the socket
connection.
The second function is on_change_layer, which mainly handles events
LCO_NEW_LAYER, LCO_DEL_LAYER, and LCO_TOPMOST_CHANGED. When system
creates new layers, this function will create a new button in taskbar and
assign the handle value of this button to dwAddData member of the current
layer; when system deletes a certain layer, the function destroys the button
corresponding the layer; when the top-most layer of system changes, the
function calls on_change_topmost to adjust the state of these buttons
representing layers. The code of this function is as follows:
2. ServerStartup function
This function initializes the server, i.e. mginit. It creates the shared
resource, the listening socket, the default layer, and other internal objects.
Your costomized mginit program should call this function before calling any
other function. Note that the default layer created by the server called
“mginit" (NAME_DEF_LAYER). The prototype of this function is:
You can pass some arguments to this function to control the limits of the window management:
nr_globalsThe number of the global z-order nodes. All z-order nodes created bymginitare global ones.def_nr_topmostsThe maximal number of the topmost z-order nodes in the default layer. It is also the default number of topmost z-order nodes of a new layer.def_nr_normalsThe maximal number of normal z-order nodes in the new layer. It is also the default number of normal z-order nodes of a new layer.
Creating Taskbar
As mentioned above, mginit uses taskbar and buttons on the taskbar to
represent the current layers of system. It also provides a simple user
interface (see Figure 1):
- If the user clicks an icon on the taskbar, a certain application program will be started.
- If the user clicks the buttons on the taskbar, it will switch the layer to be the top-most layer.
<img src="%ATTACHURLPATH%/17.1.jpeg" alt="17.1.jpeg" ALIGN="CENTER" />
Figure 1 Taskbar created by mginit in mg-samples
This taskbar uses the cool bar control to create a toolbar used to startup applications. It reads application configuration information from mginit.rc file and initializes the information, including name, description string, and corresponding program icon of application.
Taskbar also creates a timer and a static control, which displays current time and refreshs once per second.
As this code is not the proprietary of mginit, so we will not discuss it in detail.
Startup the Default Program
mginit.rc file defines an initial application that needs to startup by default. The following code startups this application program:
Then, mginit catches the signal SIGCHLD, which helps to avoid the zombie
processes if the child exits while there is no process getting its exit state:
The function exec_app used to startup client application program is very
simple. It calls vfork and execl system calls to startup a client:
Entering Message Loop
Now, mginit program enters message loop:
When the taskbar exits, the message loop will be terminated. Finally,
MiniGUI-Processes exits.
A Simple mginit Program
mginit in mg-samples is not too complex. It illustrates a basic design
method of the MiniGUI-Processes server program. In this section, we will
design a simpler mginit program, which initializes itself as the server of
MiniGUI-Processes and startups helloworld program. This program also
illustrates the use of the event hook. When the user presses the key F1, F2,
F3, or F4, some other clients will be started up. If the user has not operated
for a long time, mginit will startup a screen saver program. When the user
closes all clients, mginit exits. List 1 lists the code of this mginit
program; you can refer to file mginit.c and file scrnsaver.c in the program
package mg-sample of this guide for the whole code.
List 1 The code of a simple mginit program
This program sets the OnNewDelClient event handling function of mginit. It
will set the global variable quit as TRUE when the event handling function
encounter LCO_DEL_CLIENT, so as to result in the stop of the message loop,
and finally exits the server.
You can compile the program by using the following command:
As this mginit program need startup helloworld program when starting up, so,
we have to make sure that there is helloworld program in the current directory.
Functions Specific to Clients of MiniGUI-Processes
As you know, a client of MiniGUI-Processes should call JoinLayer to join
itself into a layer before calling other functions of MiniGUI. Besides
JoinLayer, a client can call other functions to get the information of
layers, delete a layer or change the topmost layer.
Clients should call JoinLayer before calling any other MiniGUI functions. The
prototype of this function is as follows:
If the layer to be joined does not exist, the server will try to create a new
one. If you passed a NULL pointer or a null string for layer_name, the
client will be tried to join to the default layer. If the client wants to
create a new layer, you should specify the maximal number of topmost frame
objects (max_nr_topmosts) and the maximal number of normal frame objects
(max_nr_normals) in the new layer. Passing zero to max_nr_topmosts and
max_nr_normals will use the default values. Note that ServerStartup
specifies the default values.
You can get the information of a layer through the function GetLayerInfo. The
prototype of this function is as follows:
The information of the layer will be returned through the pointer arguments if
the specific pointer is not NULL. The information are the number of clients
in the layer, whether the layer is the topmost one, and the client identifier
whose window is the current active one respectively.
Clients can call SetTopmostLayer to set the topmost layer and call
DeleteLayer to delete a layer. Detail information about these functions can
be referred to MiniGUI API Reference.
Other Functions and Interfaces Specific to mginit
Apart from ServerStartup, OnNewDelClient, and mgClients,
MiniGUI-Processes also defines several interfaces for mginit program. These
interfaces are specific to the MiniGUI-Processes server programs. Detail
information about these interfaces can be referred to MiniGUI API Reference.
ServerSetTopmostLayer:This function switches the specified layer to be the topmost layer.ServerCreateLayer:This function creates a specified layer in the system.ServerDeleteLayer:This function deletes a specified layer from the system.GetClientByPID:This function returns the client identifier according to pid of a client.SetTopmostClient:This function sets the topmost layer by the specified client identifier. It will bring the layer contains the client to be the topmost one.SetServerEventHook:This function sets a hook of bottom event in mginit. When hook function return zero to MiniGUI, MiniGUI will continue the event process, and send the event to the current active client; whereas stops the process of the event.- Send2Client: The server can use this function to send the specific message to a certain client.
- Send2TopMostClients: The server can send a message to all clients in the topmost layer.
- Send2ActiveWindow: The server can send a message to the active window in a layer.
ServerGetNextZNode:Getthe next z-node in the specified layer from the server.ServerGetZNodeInfo:Getthe z-node information in the specified layer from the server.ServerDoZNodeOperation:Doesan operation on the z-node in the specified layer from the server.
-- Main.XiaodongLi - 07 Nov 2009
<< | Table of Contents | >>