커널 2.6.9 마이크로 윈도우즈 마우스 띄우기... [Microwindows 0.91]
안녕하세요. 언제나 많은 도움 받아 가고 있는 얀슬입니다.
다름이 아니라, 마이크로 윈도우즈 프레임버퍼 상에서 nano-X 서버와 nanowm을 띄우고 gpm 데몬을 이용한 마우스를 사용하려고 합니다.
환경은, vmware용으로 100% 프레임버퍼로, 리눅스 커널은 2.6.9[한컴리눅스] 을 쓰고 있습니다. mou_gpm.c 에서 2.6이 디바이스 접근 경로를 /dev/input/mice 로 바꿔줬습니다. 2.6에서는 모든 마우스의 움직임을 이쪽으로 통해서 접근하는것 같습니다... (혹시 아니면.. /dev/gpmdata 란 디바이스를 생성해줘야 하는건가요?)..
우선 데몬은
/etc/init.d/gpm start -R -t ps2
라고 했습니다.
데몬은 확인하고, GPM MOUSE Y 로 셋팅된 config 를 컴파일 했습니다. nano-X 와 nanowm 은 잘 띄어지고, 응용프로그램도 잘 올라갑니다. 마이크로 윈도우즈 마우스 포인터도 정중앙에 위치 하고 있구요. 하지만, 마우스 포인터로 옮기는 순간, 서버도 꺼집니다.
혹시나해서,
/etc/init.d/gpm start
으로 해보기도 했구요. 아무런 옵션없이.
포인터라도 떠서, 마이크로 윈도우즈쪽보다는... 리눅스 상에서 마우스가... 잘 안되는것 같습니다. 아싸리 config에서 마우스를 죽이고 컴파일 하면, 어플리케이션은 잘 돌아갑니다. 마우스만 올리면.. 이렇게 nano-X 서버와 nanowm이 꺼져버립니다. ㅠㅠ
혹시라도 아시는 분이 있다면.. 알려주시면 감사하겠습니다. 2.6.x 버젼에 microwindows를 프레임버퍼상에서 써 보신 분이라면.. 알려주시면 감사드리겠습니다....
그럼, 고수님의 손길을 기다리며...ㅠㅠㅠ.
저도 비슷한 문제로 고민하고 있습니다
우선, 제 환경은,
HOST PC에 VmWare를 깔고, 그 위에 microwindow를 깔았습니다.
타겟 보드는 ARM을 쓰고요. Host kernel version 2.4, Target Version 2.6 입니다.
nano-x는 0.9버전을 쓰고 있습니다.
결론만 말씀드리면, PC환경에서는 마우스가 잘 되는데, 타겟 보드에서는 마우스 인식이 안 되더군요.
PC에서의 마우스는 , nano-x자체를 xwindow에서 올렸습니다.
그랬더니 잘 돌아가구요.
타겟 보드에선, 마우스 인식 자체가 안 됩니다.
컴파일 할 때 마우스 옵션을 끄면 프로그램은 돌아가는데요,
타겟 보드가 PS2 port, USB port가 있어서 당연히 mouse가 돌아갈 것이라 생각했는데, 실제 usb나 ps2 port에 마우스 꼽고 nano-x application돌려도, 마우스 인식이 안되더라구요.
현재 타겟 보드용 kernel은 2.4 / 2.6버전 둘다 있는데요. 둘 다 같은 현상이 일어납니다.
참고가 되실련지 모르겠네요.
(음...써놓고 보니 참고가 안 될 듯. -_-;;)
만일, 인식 되면, 알려주시길.. -_-;;
ARM S3C2440A nano-X 마우스 포팅
현재 nano-X을 하고 있는데요,
제 환경은
- S3C2440A 보드
- 커널 2.6.13
- USB 마우스
- USB 키보드
- 터치 패널
여기서는 마우스 인식이
Input Event 방식인데
/dev/input/event0 -> 키
/dev/input/event1 -> 터치
/dev/input/event2 -> USB 장치 -> USB 키보드
/dev/input/event3 -> USB 장치 -> USB 마우스
등으로 구별 됩니다.
root@icom4u:/dev/input# ls
event0 event1 event2 event3 mice mouse0 mouse1
으로 나타 납니다. USB 허브에 의해 동작 하기 때문에 event2와 event3는 어느 것이 마우스 인지는
알 수 없습니다. 마우스와 키보드의 포트를 서로 바꾸어 연결하면 다르게 나타납니다.
이런 경우 인식은 다음을 읽어 판단하는 것이 가장 간단한 방법 이라고 보여 집니다.
root@icom4u:/proc/bus/input# cat devices
I: Bus=001b Vendor=dead Product=beef Version=0001
N: Name="s3c2410-buttons"
P: Phys=input/s3c2440_buttons
H: Handlers=kbd event0
B: EV=3
B: KEY=1680 0 2000000 1000087c
I: Bus=001a Vendor=dead Product=beef Version=0101
N: Name="s3c2410 TouchScreen"
P: Phys=input/ts0
H: Handlers=mousedev event1
B: EV=b
B: KEY=400 0 0 0 0 0 0 0 0 0 0
B: ABS=1000003
I: Bus=0003 Vendor=05af Product=0803 Version=0001
N: Name="JME CO., LTD. USB Keyboard"
P: Phys=usb-s3c24xx-1.1/input0
H: Handlers=kbd event2
B: EV=120003
B: KEY=10000 7 ff800000 7ff febeffdf f7cfffff ffffffff fffffffe
B: LED=1f
I: Bus=0003 Vendor=046d Product=c016 Version=0340
N: Name="Logitech Optical USB Mouse"
P: Phys=usb-s3c24xx-1.3/input0
H: Handlers=mousedev event3
B: EV=7
B: KEY=70000 0 0 0 0 0 0 0 0
B: REL=103
이 정보를 읽어 어느 것이 마우스 인지를 판단하고 nano-X driver와 연결 하면 가능할 것으로 보입니다.
현재 멀티 마우스 키보드를 프로그램 하고 있어서 이것을 하지 않아 프로그램은 없습니다.
여기서 event0,... 을 단순히 나열하는 것이 아니고 의미 있는 단어를 넣어
usbkbdevt0등으로 이름을 바꾸려면 커널을 수정 해야 될것 같아 넘어 갔습니다만...
nano-X의 수정은
1. src/config
GPMMOUSE = N
INEVTMOUSE = Y
2. object 추가 - drivers/Objects.rules
### input event interface
ifeq ($(INEVTMOUSE), Y)
MW_CORE_OBJS += $(MW_DIR_OBJ)/drivers/mou_inevt.o
endif
3. drivers/mou_inevt.c : mou_null.c의 골격을 사용하여 만듬.
중요 부분만 보면
...
MOUSEDEVICE mousedev = {
INEVT_Open,
INEVT_Close,
INEVT_GetButtonInfo,
INEVT_GetDefaultAccel,
INEVT_Read,
NULL,
MOUSE_NORMAL /* flags*/
};
struct input_event event_buf; -> 커널2.6.13의 input.h에 정의
/*
* Attempt to read bytes from the mouse and interpret them.
* Returns -1 on error, 0 if either no bytes were read or not enough
* was read for a complete state, or 1 if the new state was read.
* When a new state is read, the current buttons and x and y deltas
* are returned. This routine does not block.
*/
static int
INEVT_Read(MWCOORD *dx, MWCOORD *dy, MWCOORD *dz, int *bp)
{
int nbytes;
int x,y;
static int button;
static int retcode;
static int released;
retcode = 0;
x = 0;
y = 0;
button = mkpressedstate;
nbytes = read(mouse_fd, &event_buf, sizeof(struct input_event));
if (nbytes < sizeof(struct input_event))
return -1;
switch( event_buf.type )
{
case EV_SYN:
//DPRINTF("*");
break;
case EV_KEY:
//printf("Button Code %d", event_buf.code);
retcode = 1;
released = 0;
button = mkpressedstate;
switch (event_buf.value) {
case 1 : // Pressed
switch (event_buf.code)
{
case BTN_LEFT:
button |= MWBUTTON_L;
break;
case BTN_RIGHT :
button |= MWBUTTON_R;
break;
case BTN_MIDDLE :
button |= MWBUTTON_M;
break;
}
break;
case 0 : // Release
switch (event_buf.code)
{
case BTN_LEFT:
released |= MWBUTTON_L;
break;
case BTN_RIGHT :
released |= MWBUTTON_R;
break;
case BTN_MIDDLE :
released |= MWBUTTON_M;
break;
}
button &= ~released;
break;
default:
DPRINTF("EV_KEY : type %d, code %d, value %d",
event_buf.type, event_buf.code, event_buf.value);
break;
}
mkpressedstate = button;
#ifdef IEDEBUG
DPRINTF("MKEY state = ");
if (mkpressedstate & MWBUTTON_L) printf ("MWBUTTON_L ");
if (mkpressedstate & MWBUTTON_R) printf ("MWBUTTON_R ");
if (mkpressedstate & MWBUTTON_M) printf ("MWBUTTON_M ");
DPRINTF("\n");
#endif
break;
case EV_ABS:
switch (event_buf.code)
{
case ABS_X:
retcode = 2;
x = event_buf.value;
break;
case ABS_Y:
retcode = 2;
y = event_buf.value;
break;
case ABS_PRESSURE:
printf("EV_ABS Pressure : %s\n", (event_buf.value == 1)? "yes":"no" );
break;
default:
printf("EV_ABS : type %d, code %d, value %d\n",
event_buf.type, event_buf.code, event_buf.value);
break;
}
break;
case EV_REL :
switch (event_buf.code)
{
case REL_X:
retcode = 1;
x += event_buf.value;
break;
case REL_Y:
retcode = 1;
y += event_buf.value;
break;
default:
DPRINTF("REL : type %d, code %d, value %d\n",
event_buf.type, event_buf.code, event_buf.value);
break;
}
break;
default:
DPRINTF("Unknown: type %d, code %d, value %d\n",
event_buf.type, event_buf.code, event_buf.value);
break;
}
/* button data matches defines, no conversion*/
*bp = button;
*dx = x;
*dy = y;
*dz = 0;
return retcode;
}
이 부분은 지금 시험 중이라 완전하지 않지만 참고가 되길 바랍니다. EV_ABS는 터치패널용 프로그램 입니다.
일반 마우스는 EV_REL로 read에 의해 읽히는 것입니다.
이것은 물론 nano-X 전부를 컴파일하여야 하는 문제 이라서 복잡 하기는 하나 확실 방법이라고 봅니다.
root@icom4u:/dev/input# ls -l
crw-rw---- 1 root root 13, 64 Jan 1 00:00 event0
crw-rw---- 1 root root 13, 65 Jan 1 00:00 event1
crw-rw---- 1 root root 13, 66 Jan 1 00:00 event2
crw-rw---- 1 root root 13, 67 Jan 1 00:00 event3
crw-rw---- 1 root root 13, 63 Jan 1 00:00 mice
crw-rw---- 1 root root 13, 32 Jan 1 00:00 mouse0
crw-rw---- 1 root root 13, 33 Jan 1 00:00 mouse1
여기서 input device는 minor 번호가 64, ... 을 open 하면 되는데, 나머지 이 범위를 벗어나면
nano-X에서는 잘 안되는 것으로 기억 합니다. mice나 mouse1은 잘 되지 않는 것은
아마 이것을 등록하는 것이 커널의 input이 아니라 처리 블럭이 마우스나 키보드를 처리하는 프로그램에 등록하여
제대로 연결되지 않는 것이 아닌가 쉽습니다.
ARM S3C2440A nano-X 마우스 포팅
#ifdef IEDEBUG
DPRINTF("MKEY state = ");
if (mkpressedstate & MWBUTTON_L) printf ("MWBUTTON_L ");
if (mkpressedstate & MWBUTTON_R) printf ("MWBUTTON_R ");
if (mkpressedstate & MWBUTTON_M) printf ("MWBUTTON_M ");
DPRINTF("\n");
#endif
에서
버튼이 2개 이상 눌려 button 코드를 이중으로 보내면 nano-X가 에러가 나 멈추어 버린다. 알수 없는 일이다.
*bp = mkpressedstate; => MWBUTTON_L | MWBUTTON_R --- 이런 경우 에러 발생
*dx = rel_x;
*dy = rel_y;
*dz = 0;
return 1;
이런 경우는 왼쪽 버튼이 눌린 상태에서 오른쪽 버튼이 눌리면 이런 현상이 발생한다. 그렇지만
MWBUTTON_L을 제거하고 MWBUTTON_R만 보낸다면 다음에 오는 왼쪽 release 메세지는 무시해야 하는 것인데...
해결책이 없습니다. 왜일까요???
ano-X 마우스 포팅-GPM과 에러
nano-X의 마우스는 해당 시스템 상황을 파악해서 설정해야 하는데, 현재 USB에서 어떤 방식으로 마우스가 연결되는지를 파악해야 합니다.
GPM 마우스의 경우 nano-X의
src/drivers/mou_gpm.c
에 포팅되어 있습니다. 여기서
#define GPM_DEV_FILE "/dev/gpmdata"
이와같이 디바이스 파일 이름이 설정되어 있는데 이것을 현재의 장치 이름과 맞추어 주어야 합니다.
이것은
GPM_Open(MOUSEDEVICE *pmd)
{
mouse_fd = open(GPM_DEV_FILE, O_NONBLOCK);
if (mouse_fd < 0)
return -1;
return mouse_fd;
}
에서 open 함수에 의해 열려야 하는데, 이 함수 open이 되지 않으면 return -1;되고 이 리턴값은 nano-X 서버에서
실패로 보고 마우스 포인트를 없애고 진행 합니다.
이 open 함수가 열리지 않은 경우 이것은 우서
/dev 디렉토리에 가서 /dev/gpmdata이 있는가를 확인하고 이 를 바꾸어 nano-X을 재 컴파일 해야 합니다.
만 약 이 과정이 성공하면, 마우스 포인터가 보이고 마우스 움직이 되면 마우스는 문제가 없으나 open이 잘되었다고 해서 문제가 전부 해결되지 않는 경우가 있습니다. 마우스를 움직였을 때 nano-X가 죽으면 이것은 현재 열린 마우스 형태가 맞지 않아서 입니다. GPM 마우스가 아닌 것이죠.
이것은 커널의 버전과 내 시스템를 파악해야 합니다.
static int
GPM_Read(MWCOORD *dx, MWCOORD *dy, MWCOORD *dz, int *bp)
{
static unsigned char buf[5];
static int nbytes;
int n;
while((n = read(mouse_fd, &buf[nbytes], 5 - nbytes))) {
if(n < 0) {
if ((errno == EINTR) || (errno == EAGAIN))
return 0;
else return -1;
}
여기에서 read가 되었을 때,
if(nbytes == 5) {
/* button data matches defines, no conversion*/
*bp = (~buf[0]) & 0x07;
*dx = (signed char)(buf[1]) + (signed char)(buf[3]);
*dy = -((signed char)(buf[2]) + (signed char)(buf[4]));
*dz = 0;
nbytes = 0;
return 1;
여기에서 재대로 된 데이터가 아니라는 이야기 입니다.
즉, 버퍼의 데이터가 GPM 포맷과 맞지 않는다는 이야기 입니다.
ARM S3C2440A nano-X 마우스 포팅
.
댓글 달기