MiniGUI 2.0.4/1.6.10常见问题及解答之运行及使用相关问题
1 在 Linux 控制台上运行 MiniGUI 程序,为什么我的鼠标无法正常工作?
1.1 较短回答
在 Linux 上使用 console 输入引擎,如果鼠标无法正常工作,则可能的原因主要有如下几个:
- 未正确指定鼠标设备。请修改 MiniGUI 运行时配置的 mdev,正确指定鼠标设备,同时请检查您是否有权限打开这个设备读取数据,如果没有,请使用 chmod 命令修改该设备的访问许可。
- 未正确指定鼠标设备的协议。这时,请修改 MiniGUI 运行时配置的 mtype,指定正确的鼠标协议,如 PS2 或者 IMPS2。
1.2 完整回答
在 Linux 上使用 console 输入引擎运行
MiniGUI,如果鼠标无法正常工作,则可能的原因主要有如下几个:
1.2.1 鼠标设备
请首先检查正确的鼠标设备名称。在 Linux 操作系统上,在 2.4.18 内核之前,鼠标设备的名称一般为 /dev/mouse。这通常是一个符号链接,链接到正确的鼠标设备上,比如 /dev/psaux(PS2 接口);在 2.4.18 内核及以上,鼠标设备 的名称一般为 /dev/input/mice。这个设备是一个逻辑设备,如果您的机器上连接有多个鼠标设备(比如笔记本的触摸板以及 USB 口上的鼠标设备),则访问这个设备,可同时获得这两个设备上的鼠标数据(这通过 mice 是 mouse 的英文复数形式可以看出来)。
在确定正确的鼠标设备之后,请检查您是否有权限访问这个设备,使用如下的命令:
$ ls -l /dev/psaux
crw-rw-rw- 1 root root 10, 1 4月 11 2002 /dev/psaux
您至少要有读取该设备的许可,才能正常使用该设备。修改权限时,请使用 root 用户,并执行 chmod 命令,如:
# chmod go+r /dev/psaux
确定好正确的鼠标设备后,请修改
MiniGUI 运行时配置的 mdev 参数,指定正确的鼠标设备。
1.2.2 鼠标协议
MiniGUI 支持多种鼠标协议,比如 PS2、IMPS2、MS 等。目前,PC 上的鼠标协议一般是 IMPS2(即支持滚轮的智能鼠标协议),一些老式的鼠标其协议是 PS2(即不支持滚轮的鼠标)。如果您运行
MiniGUI 时发现在移动鼠标时,鼠标指针不受控制地乱飞,则通常是没有设置好正确的鼠标协议,这时,应该修改
MiniGUI 运行时配置地 mtype 参数,指定正确的鼠标协议,如 PS2 或者 IMPS2。
1.2.3 对应的 MiniGUI 运行时配置选项
如果您将
MiniGUI 配置成使用非内建资源的话,则应该修改
MiniGUI.cfg 文件(~/.MiniGUI.cfg 或者/usr/local/etc/MiniGUI.cfg)中的 mdev 和 mtype。如:
[system]
gal_engine=fbcon
ial_engine=console
mdev=/dev/input/mice
mtype=IMPS2
如果使用内建资源模式,则应该修改
MiniGUI 源代码树中的 src/sysres/mgetc-pc.c 文件,修改对应的字符串,如:
static char *SYSTEM_VALUES[] = {"fbcon", "console", "/dev/input/mice", "IMPS2"};
2 运行mde目录中的mginit会报错,提示:There is already an instance of 'mginit'! ,如何解决?
2.1 较短回答
退出程序时没有按照正常操作退出,sever创建的临时系统资源没有被清除导致的。
2.2 完整回答
2.2.1 出现原因
MiniGUI的lite模式或者process模式使用到了信号,这个信号属于 System V IPC。它有个缺点:System V IPC没有回收丢弃的IPC结构的自动机制,如果一个进程创建了IPC,并在其中放入数据,然后没有正常地删除IPC就退出了,那么这个IPC就会被保留到系统重启、或者其他进程删除它、或者使用ipcrm 命令删除它为止。由于mginit 是服务器,只能确保一个在运行,因而在mginit里做了相关的处理,依据就是信号是否存在。所以如果非法退出mginit,就会出现这种现象。
2.2.2 解决办法
查看/var/tmp下是否有minigui和mginit这两个临时文件,如果有则删除这两个文件:
$rm /var/tmp/minigui
$rm /var/tmp/mginit
启动mginit,如果还是提示出错,则查看信号:
$ipcs
删除 Semaphore Arrays中属于用户自己的信号:
$ipcrm -s n
(n 为信号值)
操作过程和显示如下:
[gelei@devpc34 mginit]$ ipcs
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 98305 gelei 600 393216 2 dest
0x00000000 131074 gelei 600 196608 2 dest
0x00000000 163843 gelei 600 393216 2 dest
0x00000000 196612 gelei 600 196608 2 dest
------ Semaphore Arrays --------
key semid owner perms nsems
0x464d4702 0 gelei 666 4
0x464d4703 32769 gelei 666 64
------ Message Queues --------
key msqid owner perms used-bytes messages
[gelei@devpc34 mginit]$ ipcrm -s 32769
[gelei@devpc34 mginit]$ ipcrm -s 0
3 怎样在MiniGUI中加入自己的线程
- 从本质上讲,MiniGUI就是一些c代码,这些c代码的目的是帮助开发者进行二次开发,完成嵌入式计算机图形化的人机界面,性质上极其相似qt和gdk----只是界面的开发包,不是所有(windows 把操作系统与图形界面做在了一起)。虽然MiniGUI可以移植在其他操作系统上,但是如果要完成自己的功能,还是要遵循所在操作系统的编程法则,不要被 MiniGUI用户编程里的入口函数 MiniGUIMain? 吓倒,以为到了另一环境。如果一段代码的功能和图形界面有关系,而且流程上用户代码和MiniGUI的代码属于串行关系,形式为:输入->硬件->操作系统-> minigui->用户代码->MiniGUI->操作系统->硬件->输出。否则是并列关系。
3.2 MiniGUI里的线程编程(例如Linux系统)
- 如果在Linux操作系统上使用MiniGUI开发图形界面,同时又要用线程完成非图形界面的任务(如果任务为每隔1秒打印一段信息)。
下面是一个简单的例子:
#include
#include
#include
#include
#include
#include
#include
int i=1;
void * sendMsgs(void)//线程处理函数
{
while(i){
sleep(1);
printf("Hello !\n");
}
printf("bye bye !\n");
}
static int HelloWinProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case MSG_CLOSE:
DestroyMainWindow (hWnd);
PostQuitMessage (hWnd);
i=0;
return 0;
}
return DefaultMainWinProc(hWnd, message, wParam, lParam);
}
int MiniGUIMain (int argc, const char* argv[])
{
MSG Msg;
HWND hMainWnd;
MAINWINCREATE CreateInfo;
pthread_t thread;
int ret;
#ifdef _LITE_VERSION
SetDesktopRect(0, 0, 1024, 768);
#endif
ret=pthread_create(&thread,NULL,(void *)sendMsgs,NULL);//创建线程
CreateInfo.dwStyle = WS_VISIBLE | WS_BORDER | WS_CAPTION;
CreateInfo.dwExStyle = WS_EX_NONE;
CreateInfo.spCaption = " This is a main window with a customer pthread!";
CreateInfo.hMenu = 0;
CreateInfo.hCursor = GetSystemCursor(0);
CreateInfo.hIcon = 0;
CreateInfo.MainWindowProc = HelloWinProc;
CreateInfo.lx = 100;
CreateInfo.ty = 100;
CreateInfo.rx = 600;
CreateInfo.by = 400;
CreateInfo.iBkColor = COLOR_lightwhite;
CreateInfo.dwAddData = 0;
CreateInfo.hHosting = HWND_DESKTOP;
hMainWnd = CreateMainWindow (&CreateInfo);
if (hMainWnd == HWND_INVALID)
return -1;
ShowWindow(hMainWnd, SW_SHOWNORMAL);
while (GetMessage(&Msg, hMainWnd)) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
pthread_join(thread,NULL);//等待结束线程
MainWindowThreadCleanup (hMainWnd);
return 0;
}
#ifndef _LITE_VERSION
#include
#endif
--
FeynmanHejian - 20 Feb 2009