Skip to content

Commit 0ff7b70

Browse files
committed
feat(platform): add linux mouse driver
1 parent 6015838 commit 0ff7b70

File tree

2 files changed

+145
-12
lines changed

2 files changed

+145
-12
lines changed

include/LCUI/platform/linux/linux_mouse.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* linux_mouse.h -- Mouse support for linux.
33
*
44
* Copyright (c) 2018, Liu chao <lc-soft@live.cn> All rights reserved.
5-
*
5+
*
66
* Redistribution and use in source and binary forms, with or without
77
* modification, are permitted provided that the following conditions are met:
88
*
@@ -35,8 +35,8 @@
3535
#include <LCUI/platform/linux/linux_x11mouse.h>
3636
#endif
3737

38-
void LCUI_InitLinuxMouse( void );
38+
void LCUI_InitLinuxMouse(void);
3939

40-
void LCUI_ExitLinuxMouse( void );
40+
void LCUI_FreeLinuxMouse(void);
4141

4242
#endif

src/platform/linux/linux_mouse.c

Lines changed: 142 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* linux_mouse.c -- Mouse support for linux.
33
*
44
* Copyright (c) 2018, Liu chao <lc-soft@live.cn> All rights reserved.
5-
*
5+
*
66
* Redistribution and use in source and binary forms, with or without
77
* modification, are permitted provided that the following conditions are met:
88
*
@@ -28,32 +28,165 @@
2828
* POSSIBILITY OF SUCH DAMAGE.
2929
*/
3030

31-
3231
#include <LCUI_Build.h>
3332
#ifdef LCUI_BUILD_IN_LINUX
33+
#include <stdio.h>
34+
#include <stdlib.h>
35+
#include <fcntl.h>
36+
#include <errno.h>
37+
#include <unistd.h>
38+
#include <sys/time.h>
39+
#include <sys/types.h>
40+
#include <sys/stat.h>
41+
#include <linux/input.h>
42+
3443
#include <LCUI/LCUI.h>
44+
#include <LCUI/thread.h>
3545
#include <LCUI/platform.h>
46+
#include <LCUI/display.h>
3647
#include LCUI_EVENTS_H
3748
#include LCUI_MOUSE_H
3849

39-
void LCUI_InitLinuxMouse( void )
50+
enum MouseButtonId { MOUSE_BUTTON_LEFT = 1, MOUSE_BUTTON_RIGHT = 1 << 1 };
51+
52+
static struct LCUI_LinuxMouseDriver {
53+
int x;
54+
int y;
55+
int button_state[2];
56+
57+
int dev_fd;
58+
const char *dev_path;
59+
60+
LCUI_Thread tid;
61+
LCUI_BOOL active;
62+
} mouse;
63+
64+
static void DispathMouseButtonEvent(int button, int state)
65+
{
66+
LCUI_SysEventRec ev = { 0 };
67+
if (mouse.button_state[button - 1]) {
68+
if (!(state & button)) {
69+
ev.type = LCUI_MOUSEUP;
70+
ev.button.x = mouse.x;
71+
ev.button.y = mouse.y;
72+
ev.button.button = button;
73+
mouse.button_state[button - 1] = 0;
74+
LCUI_TriggerEvent(&ev, NULL);
75+
LCUI_DestroyEvent(&ev);
76+
}
77+
} else if (state & button) {
78+
ev.type = LCUI_MOUSEDOWN;
79+
ev.button.x = mouse.x;
80+
ev.button.y = mouse.y;
81+
ev.button.button = button;
82+
mouse.button_state[button - 1] = 1;
83+
LCUI_TriggerEvent(&ev, NULL);
84+
LCUI_DestroyEvent(&ev);
85+
}
86+
}
87+
88+
static void DispatchMouseEvent(void *arg1, void *arg2)
89+
{
90+
char *buf = arg1;
91+
int state = buf[0] & 0x07;
92+
LCUI_SysEventRec ev = { 0 };
93+
94+
mouse.x += buf[1];
95+
mouse.y -= buf[2];
96+
mouse.x = max(0, mouse.x);
97+
mouse.y = max(0, mouse.y);
98+
mouse.x = min(LCUIDisplay_GetWidth(), mouse.x);
99+
mouse.y = min(LCUIDisplay_GetHeight(), mouse.y);
100+
ev.type = LCUI_MOUSEMOVE;
101+
ev.motion.x = mouse.x;
102+
ev.motion.y = mouse.y;
103+
ev.motion.xrel = buf[1];
104+
ev.motion.yrel = -buf[2];
105+
LCUI_TriggerEvent(&ev, NULL);
106+
LCUI_DestroyEvent(&ev);
107+
DispathMouseButtonEvent(MOUSE_BUTTON_LEFT, state);
108+
DispathMouseButtonEvent(MOUSE_BUTTON_RIGHT, state);
109+
}
110+
111+
static void LinuxMouseThread(void *arg)
112+
{
113+
char buf[6];
114+
fd_set readfds;
115+
struct timeval tv;
116+
LCUI_TaskRec task = { 0 };
117+
118+
mouse.active = TRUE;
119+
task.func = DispatchMouseEvent;
120+
task.destroy_arg[0] = free;
121+
while (mouse.active) {
122+
tv.tv_sec = 0;
123+
tv.tv_usec = 500000;
124+
125+
FD_ZERO(&readfds);
126+
FD_SET(mouse.dev_fd, &readfds);
127+
select(mouse.dev_fd + 1, &readfds, NULL, NULL, &tv);
128+
if (FD_ISSET(mouse.dev_fd, &readfds)) {
129+
if (read(mouse.dev_fd, buf, 6) <= 0) {
130+
continue;
131+
}
132+
task.arg[0] = malloc(sizeof(char) * 6);
133+
if (!task.arg[0]) {
134+
perror("[input] mouse driver");
135+
continue;
136+
}
137+
memcpy(task.arg[0], buf, sizeof(char) * 6);
138+
LCUI_PostTask(&task);
139+
}
140+
}
141+
}
142+
143+
static int InitLinuxMouse(void)
144+
{
145+
mouse.x = LCUIDisplay_GetWidth() / 2;
146+
mouse.y = LCUIDisplay_GetHeight() / 2;
147+
mouse.dev_path = getenv("LCUI_MOUSE_DEVICE");
148+
if (!mouse.dev_path) {
149+
mouse.dev_path = "/dev/input/mice";
150+
}
151+
LOG("[input] open mouse device: %s\n", mouse.dev_path);
152+
if ((mouse.dev_fd = open(mouse.dev_path, O_RDONLY)) < 0) {
153+
perror("[input] open mouse device failed");
154+
return -1;
155+
}
156+
LCUIThread_Create(&mouse.tid, LinuxMouseThread, NULL);
157+
LOG("[input] mouse driver thread: %lld\n", mouse.tid);
158+
return 0;
159+
}
160+
161+
static void FreeLinuxMouse(void)
162+
{
163+
if (mouse.active) {
164+
mouse.active = FALSE;
165+
LCUIThread_Join(mouse.tid, NULL);
166+
close(mouse.dev_fd);
167+
}
168+
}
169+
170+
void LCUI_InitLinuxMouse(void)
40171
{
41172
#ifdef LCUI_VIDEO_DRIVER_X11
42-
LCUI_BOOL is_x11_mode = TRUE;
43-
if( is_x11_mode ) {
173+
if (LCUI_GetAppId() == LCUI_APP_LINUX_X11) {
44174
LCUI_InitLinuxX11Mouse();
175+
return;
45176
}
46177
#endif
178+
InitLinuxMouse();
47179
}
48180

49-
void LCUI_ExitLinuxMouse( void )
181+
void LCUI_FreeLinuxMouse(void)
50182
{
51183
#ifdef LCUI_VIDEO_DRIVER_X11
52-
LCUI_BOOL is_x11_mode = TRUE;
53-
if( is_x11_mode ) {
54-
LCUI_ExitLinuxX11Mouse();
184+
if (LCUI_GetAppId() == LCUI_APP_LINUX_X11) {
185+
LCUI_FreeLinuxX11Mouse();
186+
return;
55187
}
56188
#endif
189+
FreeLinuxMouse();
57190
}
58191

59192
#endif

0 commit comments

Comments
 (0)