@@ -36,6 +36,7 @@ typedef struct {
3636 int fd ;
3737 int btns ;
3838 int x , y ;
39+ int abs_x_max , abs_y_max ; /* Maximum value for ABS_X/ABS_Y from device */
3940} twin_linux_input_t ;
4041
4142static void check_mouse_bounds (twin_linux_input_t * tm )
@@ -79,16 +80,21 @@ static void twin_linux_input_events(struct input_event *ev,
7980 }
8081 break ;
8182 case EV_ABS :
82- if (ev -> code == ABS_X ) {
83- tm -> x = ev -> value ;
83+ /* Scale absolute coordinates to screen resolution.
84+ * The range is dynamically queried from each device using EVIOCGABS.
85+ * If no device reported ABS info, we fall back to the common default
86+ * of 32767 for touchscreens and absolute pointing devices.
87+ */
88+ if (ev -> code == ABS_X && tm -> abs_x_max > 0 ) {
89+ tm -> x = ((int64_t ) ev -> value * tm -> screen -> width ) / tm -> abs_x_max ;
8490 check_mouse_bounds (tm );
8591 tev .kind = TwinEventMotion ;
8692 tev .u .pointer .screen_x = tm -> x ;
8793 tev .u .pointer .screen_y = tm -> y ;
8894 tev .u .pointer .button = tm -> btns ;
8995 twin_screen_dispatch (tm -> screen , & tev );
90- } else if (ev -> code == ABS_Y ) {
91- tm -> y = ev -> value ;
96+ } else if (ev -> code == ABS_Y && tm -> abs_y_max > 0 ) {
97+ tm -> y = (( int64_t ) ev -> value * tm -> screen -> height ) / tm -> abs_y_max ;
9298 check_mouse_bounds (tm );
9399 tev .kind = TwinEventMotion ;
94100 tev .u .pointer .screen_x = tm -> x ;
@@ -169,6 +175,26 @@ static bool twin_linux_udev_update(struct udev_monitor *mon)
169175 return false;
170176}
171177
178+ /* Query absolute axis information from an input device */
179+ static void twin_linux_input_query_abs (int fd , twin_linux_input_t * tm )
180+ {
181+ struct input_absinfo abs_info ;
182+
183+ /* Query ABS_X maximum value */
184+ if (ioctl (fd , EVIOCGABS (ABS_X ), & abs_info ) == 0 && abs_info .maximum > 0 ) {
185+ /* Update global maximum if this device has a larger range */
186+ if (abs_info .maximum > tm -> abs_x_max )
187+ tm -> abs_x_max = abs_info .maximum ;
188+ }
189+
190+ /* Query ABS_Y maximum value */
191+ if (ioctl (fd , EVIOCGABS (ABS_Y ), & abs_info ) == 0 && abs_info .maximum > 0 ) {
192+ /* Update global maximum if this device has a larger range */
193+ if (abs_info .maximum > tm -> abs_y_max )
194+ tm -> abs_y_max = abs_info .maximum ;
195+ }
196+ }
197+
172198static void twin_linux_edev_open (struct pollfd * pfds , twin_linux_input_t * tm )
173199{
174200 /* New event device list */
@@ -201,6 +227,8 @@ static void twin_linux_edev_open(struct pollfd *pfds, twin_linux_input_t *tm)
201227 /* Open the file if it is not on the list */
202228 int fd = open (evdev_name , O_RDWR | O_NONBLOCK );
203229 if (fd > 0 && !opened ) {
230+ /* Query absolute axis info for newly opened devices */
231+ twin_linux_input_query_abs (fd , tm );
204232 evdevs [new_evdev_cnt ].idx = i ;
205233 evdevs [new_evdev_cnt ].fd = fd ;
206234 new_evdev_cnt ++ ;
@@ -293,6 +321,11 @@ void *twin_linux_input_create(twin_screen_t *screen)
293321
294322 tm -> screen = screen ;
295323
324+ /* Initialize ABS axis ranges to common touchscreen default.
325+ * These will be updated to actual device values when devices are opened.
326+ */
327+ tm -> abs_x_max = tm -> abs_y_max = 32767 ;
328+
296329 /* Centering the cursor position */
297330 tm -> x = screen -> width / 2 ;
298331 tm -> y = screen -> height / 2 ;
0 commit comments