... | ... | @@ -75,14 +75,15 @@ have no such device, the engine will fails to initialize. |
|
|
#### Initializing the engine
|
|
|
|
|
|
`__commlcd_drv_init` will be called when initializing your
|
|
|
CommLCD engine implementation. In the `commlcd` sample, it does nothing
|
|
|
CommLCD engine implementation. In the `comm-engines` sample, it does nothing
|
|
|
and just returns zero:
|
|
|
|
|
|
int __commlcd_drv_init (void)
|
|
|
{
|
|
|
```
|
|
|
int __commlcd_drv_init (void)
|
|
|
{
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
```
|
|
|
|
|
|
Note that, all external methods for CommLCD engine should return zero for success.
|
|
|
|
... | ... | @@ -95,8 +96,9 @@ mode according to your settings in the MiniGUI runtime configuration, e.g., |
|
|
In our sample, it creates an anonymous memory map by calling `mmap` system
|
|
|
call and returns the video information via `struct commlcd_info* li`:
|
|
|
|
|
|
int __commlcd_drv_getinfo (struct commlcd_info *li, int width, int height, int depth)
|
|
|
{
|
|
|
```
|
|
|
int __commlcd_drv_getinfo (struct commlcd_info *li, int width, int height, int depth)
|
|
|
{
|
|
|
sg_fb = (BYTE*) mmap (0, FB_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
|
|
|
if (sg_fb == MAP_FAILED) {
|
|
|
perror ("Failed calling __commlcd_drv_getinfo: ");
|
... | ... | @@ -111,7 +113,8 @@ call and returns the video information via `struct commlcd_info* li`: |
|
|
li->update_method = COMMLCD_UPDATE_ASYNC;
|
|
|
li->fb = sg_fb;
|
|
|
return 0;
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
You need to fill the all fields of `struct commlcd_info* li` with the correct
|
|
|
values:
|
... | ... | @@ -144,10 +147,12 @@ If the color depth of the video mode is 8 (`COMMLCD_PSEUDO_RGB332`), |
|
|
|
|
|
In our sample, this method does nothing and returns zero:
|
|
|
|
|
|
int __commlcd_drv_setclut (int firstcolor, int ncolors, GAL_Color *colors)
|
|
|
{
|
|
|
```
|
|
|
int __commlcd_drv_setclut (int firstcolor, int ncolors, GAL_Color *colors)
|
|
|
{
|
|
|
return 0;
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
In practice, you should set the hardware palette (color look up table) in this
|
|
|
method if the color depth of your video device is only 256-color.
|
... | ... | @@ -161,8 +166,9 @@ The arguments of this function have the following meanings: |
|
|
|
|
|
`GAL_Color` is a structure defined in MiniGUI header:
|
|
|
|
|
|
typedef struct _GAL_Color
|
|
|
{
|
|
|
```
|
|
|
typedef struct _GAL_Color
|
|
|
{
|
|
|
/**
|
|
|
* The red component of a RGBA quarter.
|
|
|
*/
|
... | ... | @@ -179,7 +185,8 @@ The arguments of this function have the following meanings: |
|
|
* The alpha component of a RGBA quarter.
|
|
|
*/
|
|
|
gal_uint8 a;
|
|
|
} GAL_Color;
|
|
|
} GAL_Color;
|
|
|
```
|
|
|
|
|
|
#### Update method
|
|
|
|
... | ... | @@ -190,8 +197,9 @@ be called frequently or periodically. |
|
|
In our sample, this method saves the whole frame buffer content to Windows
|
|
|
bitmap files by calling MiniGUI function:
|
|
|
|
|
|
int __commlcd_drv_update (const RECT* rc_dirty)
|
|
|
{
|
|
|
```
|
|
|
int __commlcd_drv_update (const RECT* rc_dirty)
|
|
|
{
|
|
|
char filename [PATH_MAX + 1];
|
|
|
struct timeval tv;
|
|
|
|
... | ... | @@ -214,7 +222,8 @@ bitmap files by calling MiniGUI function: |
|
|
sprintf (filename, "screenshot-%d.%d.bmp", (int)tv.tv_sec, (int)tv.tv_usec);
|
|
|
SaveMyBitmapToFile (&my_bmp, NULL, filename);
|
|
|
return 0;
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
Note that, you can not call MiniGUI GDI functions here to draw something to
|
|
|
screen.
|
... | ... | @@ -260,27 +269,200 @@ the resource allocated or created by the engine. |
|
|
|
|
|
In our sample, it destroys the anonymous memory map and returns zero:
|
|
|
|
|
|
int __commlcd_drv_release (void)
|
|
|
{
|
|
|
```
|
|
|
int __commlcd_drv_release (void)
|
|
|
{
|
|
|
munmap (sg_fb, FB_SIZE);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
```
|
|
|
|
|
|
### Comm IAL engine
|
|
|
|
|
|
#### Initializing the engine
|
|
|
|
|
|
When you specify MiniGUI runtime configuration option `system.ial_engine=comm`,
|
|
|
MiniGUI will call `__comminput_init` function to initialize the engine.
|
|
|
|
|
|
You can open your input devices in the function:
|
|
|
|
|
|
```
|
|
|
#define POWER_EVENT_DEV "/dev/input/event0"
|
|
|
#define KB_EVENT_DEV "/dev/input/event1"
|
|
|
#define TP_EVENT_DEV "/dev/input/event5"
|
|
|
|
|
|
static int sg_power_event_fd;
|
|
|
static int sg_kb_event_fd;
|
|
|
static int sg_tp_event_fd;
|
|
|
static int sg_current_kb_event_fd;
|
|
|
|
|
|
int __comminput_init (void)
|
|
|
{
|
|
|
sg_kb_event_fd = open (KB_EVENT_DEV, O_RDWR);
|
|
|
if (sg_kb_event_fd < 0) {
|
|
|
perror ("WARNING > __comminput_init: Failed when opening key-button event device file");
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
sg_tp_event_fd = open (TP_EVENT_DEV, O_RDWR /*| O_NONBLOCK */);
|
|
|
if (sg_tp_event_fd < 0) {
|
|
|
perror ("WARNING > __comminput_init: Failed when opening touch-panel event device file");
|
|
|
close (sg_kb_event_fd);
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
sg_power_event_fd = open (POWER_EVENT_DEV, O_RDWR);
|
|
|
if (sg_power_event_fd < 0) {
|
|
|
perror ("WARNING > __comminput_init: Failed when opening power key-button event device file");
|
|
|
return -1;
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
```
|
|
|
|
|
|
In `comm-engines` sample, the engine opens three Linux input devices:
|
|
|
|
|
|
- `/dev/input/event0`: A power key.
|
|
|
- `/dev/input/event1`: Some buttons on the devices.
|
|
|
- `/dev/input/event5`: A touch panel.
|
|
|
|
|
|
The function returns zero for success.
|
|
|
|
|
|
Note that the real device file names may change according to your
|
|
|
implementation of the Linux device drivers.
|
|
|
|
|
|
The engine will translate the input events generated by the device into
|
|
|
MiniGUI input messages:
|
|
|
|
|
|
- The power key: The down and up message of the standard keyboard key with
|
|
|
the scan code (key code) `SCANCODE_POWER`.
|
|
|
- The touch panel: The standard mouse messages such as mouse move,
|
|
|
and left button down and up.
|
|
|
- Other buttons: Some standard keyboard keys with scan code
|
|
|
`SCANCODE_ESCAPE` or others.
|
|
|
|
|
|
#### Waiting for an event
|
|
|
|
|
|
After MiniGUI starts up, your MiniGUI app will enter an event loop and call
|
|
|
`GetMessage` function continually. Eventually, MiniGUI calls
|
|
|
`__comminput_wait_for_input` function if you were using the Comm IAL engine.
|
|
|
|
|
|
As the name implies, `__comminput_wait_for_input` will give the engine a chance
|
|
|
to wait for a new event, but in a specified time interval. If there is no input
|
|
|
event in the time interval, the function should return 0 for timeout, and -1
|
|
|
for error.
|
|
|
|
|
|
Indeed, Comm IAL engine is a simplified implementation of a typical IAL engine.
|
|
|
When there is an event, you should return an integer with `COMM_KBINPUT`
|
|
|
and/or `COMM_MOUSEINPUT` set, in order to tell MiniGUI there is a mouse event
|
|
|
and/or a keyboard event. The sample implementation of `__comminput_wait_for_input`
|
|
|
uses the system call `select` to check the file descriptors opened by
|
|
|
`__comminput_init`, and return a suitable value to MiniGUI:
|
|
|
|
|
|
```
|
|
|
int __comminput_wait_for_input (struct timeval *timeout)
|
|
|
{
|
|
|
fd_set rfds;
|
|
|
int retval;
|
|
|
int event_flag = 0;
|
|
|
|
|
|
FD_ZERO (&rfds);
|
|
|
FD_SET (sg_kb_event_fd, &rfds);
|
|
|
FD_SET (sg_tp_event_fd, &rfds);
|
|
|
FD_SET (sg_power_event_fd, &rfds);
|
|
|
|
|
|
retval = select (MAX(MAX (sg_kb_event_fd, sg_tp_event_fd), sg_power_event_fd) + 1, &rfds, NULL, NULL, timeout);
|
|
|
|
|
|
if (retval > 0) {
|
|
|
if (FD_ISSET (sg_kb_event_fd, &rfds)) {
|
|
|
event_flag |= COMM_KBINPUT;
|
|
|
sg_current_kb_event_fd = sg_kb_event_fd;
|
|
|
}
|
|
|
|
|
|
if (FD_ISSET (sg_tp_event_fd, &rfds)) {
|
|
|
event_flag |= COMM_MOUSEINPUT;
|
|
|
}
|
|
|
|
|
|
if (FD_ISSET (sg_power_event_fd, &rfds)) {
|
|
|
event_flag |= COMM_KBINPUT;
|
|
|
sg_current_kb_event_fd = sg_power_event_fd;
|
|
|
}
|
|
|
}
|
|
|
else if (retval < 0) {
|
|
|
event_flag = -1;
|
|
|
}
|
|
|
|
|
|
return event_flag;
|
|
|
}
|
|
|
```
|
|
|
|
|
|
#### Getting mouse/touch event
|
|
|
|
|
|
If there is a keyboard event (the return value of `__comminput_wait_for_input`
|
|
|
has the bit `COMM_KBINPUT` set), MiniGUI will call `__comminput_kb_getdata`
|
|
|
immediately to get the real keyboard event data:
|
|
|
|
|
|
```
|
|
|
int __comminput_kb_getdata (short *key, short *status)
|
|
|
{
|
|
|
...
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
The function returns zero for success, and the scan code of the key pressed
|
|
|
or released through the pointers of `key` and `status`.
|
|
|
|
|
|
For the detailed implementation, please refer to:
|
|
|
|
|
|
<https://github.com/VincentWei/mg-tests/blob/master/comm-engines/comminput_ops.c>
|
|
|
|
|
|
#### Getting keyboard event
|
|
|
|
|
|
If there is a mouse event (the return value of `__comminput_wait_for_input`
|
|
|
has the bit `COMM_MOUSEINPUT` set), MiniGUI will call `__comminput_ts_getdata`
|
|
|
immediately to get the real keyboard event data:
|
|
|
|
|
|
```
|
|
|
int __comminput_ts_getdata (short *x, short *y, short *button)
|
|
|
{
|
|
|
...
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
The function returns zero for success, and the mouse position and button status
|
|
|
through the pointers of `x`, `y` and `status`.
|
|
|
|
|
|
For the detailed implementation, please refer to:
|
|
|
|
|
|
<https://github.com/VincentWei/mg-tests/blob/master/comm-engines/comminput_ops.c>
|
|
|
|
|
|
#### Terminating the engine
|
|
|
|
|
|
When MiniGUI quits, it will call `__comminput_deinit` to release
|
|
|
the resource allocated or created by the Comm IAL engine.
|
|
|
|
|
|
In our sample, it just closes the file descriptors:
|
|
|
|
|
|
```
|
|
|
void __comminput_deinit (void)
|
|
|
{
|
|
|
close (sg_tp_event_fd);
|
|
|
close (sg_kb_event_fd);
|
|
|
close (sg_power_event_fd);
|
|
|
}
|
|
|
```
|
|
|
|
|
|
## Restrictions
|
|
|
|
|
|
As we pointed out, these two engines are simplified implementations of
|
|
|
typical NEWGAL engine and IAL engine. Therefore, there are some restrictions
|
|
|
can not be implemented by these two engines:
|
|
|
|
|
|
- You can not implement the hardware-accelerated operations by using CommLCD engine.
|
|
|
- You can not implement the extra input events introduced by MiniGUI 4.0.
|
|
|
|
|
|
## References
|
|
|
|
|
|
* [GAL and IAL Engines](http://wiki.minigui.com/twiki/bin/view/Products/MiniGUIPGV32Part5Chapter03)
|
... | ... | |