1 /**
2 * @file lv_sdl_mousewheel.c
3 *
4 */
5
6 /*********************
7 * INCLUDES
8 *********************/
9 #include "lv_sdl_mousewheel.h"
10 #if LV_USE_SDL && LV_SDL_MOUSEWHEEL_MODE == LV_SDL_MOUSEWHEEL_MODE_ENCODER
11
12 #include "../../core/lv_group.h"
13 #include "../../stdlib/lv_string.h"
14 #include "lv_sdl_private.h"
15
16 /*********************
17 * DEFINES
18 *********************/
19
20 /**********************
21 * STATIC PROTOTYPES
22 **********************/
23 static void sdl_mousewheel_read(lv_indev_t * indev, lv_indev_data_t * data);
24 static void release_indev_cb(lv_event_t * e);
25
26 /**********************
27 * STATIC VARIABLES
28 **********************/
29
30 typedef struct {
31 int16_t diff;
32 lv_indev_state_t state;
33 } lv_sdl_mousewheel_t;
34
35 /**********************
36 * GLOBAL FUNCTIONS
37 **********************/
38
lv_sdl_mousewheel_create(void)39 lv_indev_t * lv_sdl_mousewheel_create(void)
40 {
41 lv_sdl_mousewheel_t * dsc = lv_malloc_zeroed(sizeof(lv_sdl_mousewheel_t));
42 LV_ASSERT_MALLOC(dsc);
43 if(dsc == NULL) return NULL;
44
45 lv_indev_t * indev = lv_indev_create();
46 if(indev == NULL) {
47 lv_free(dsc);
48 return NULL;
49 }
50
51 lv_indev_set_type(indev, LV_INDEV_TYPE_ENCODER);
52 lv_indev_set_read_cb(indev, sdl_mousewheel_read);
53 lv_indev_set_driver_data(indev, dsc);
54
55 lv_indev_set_mode(indev, LV_INDEV_MODE_EVENT);
56 lv_indev_add_event_cb(indev, release_indev_cb, LV_EVENT_DELETE, indev);
57
58 return indev;
59 }
60
61 /**********************
62 * STATIC FUNCTIONS
63 **********************/
64
sdl_mousewheel_read(lv_indev_t * indev,lv_indev_data_t * data)65 static void sdl_mousewheel_read(lv_indev_t * indev, lv_indev_data_t * data)
66 {
67 lv_sdl_mousewheel_t * dsc = lv_indev_get_driver_data(indev);
68
69 data->state = dsc->state;
70 data->enc_diff = dsc->diff;
71 dsc->diff = 0;
72 }
73
release_indev_cb(lv_event_t * e)74 static void release_indev_cb(lv_event_t * e)
75 {
76 lv_indev_t * indev = (lv_indev_t *) lv_event_get_user_data(e);
77 lv_sdl_mousewheel_t * dsc = lv_indev_get_driver_data(indev);
78 if(dsc) {
79 lv_indev_set_driver_data(indev, NULL);
80 lv_indev_set_read_cb(indev, NULL);
81 lv_free(dsc);
82 LV_LOG_INFO("done");
83 }
84 }
85
lv_sdl_mousewheel_handler(SDL_Event * event)86 void lv_sdl_mousewheel_handler(SDL_Event * event)
87 {
88 uint32_t win_id = UINT32_MAX;
89 switch(event->type) {
90 case SDL_MOUSEWHEEL:
91 win_id = event->wheel.windowID;
92 break;
93 case SDL_MOUSEBUTTONDOWN:
94 case SDL_MOUSEBUTTONUP:
95 win_id = event->button.windowID;
96 break;
97 default:
98 return;
99 }
100
101 lv_display_t * disp = lv_sdl_get_disp_from_win_id(win_id);
102
103 /*Find a suitable indev*/
104 lv_indev_t * indev = lv_indev_get_next(NULL);
105 while(indev) {
106 if(lv_indev_get_read_cb(indev) == sdl_mousewheel_read) {
107 /*If disp is NULL for any reason use the first indev with the correct type*/
108 if(disp == NULL || lv_indev_get_display(indev) == disp) break;
109 }
110 indev = lv_indev_get_next(indev);
111 }
112
113 if(indev == NULL) return;
114 lv_sdl_mousewheel_t * dsc = lv_indev_get_driver_data(indev);
115
116 switch(event->type) {
117 case SDL_MOUSEWHEEL:
118 #ifdef __EMSCRIPTEN__
119 /*Emscripten scales it wrong*/
120 if(event->wheel.y < 0) dsc->diff++;
121 if(event->wheel.y > 0) dsc->diff--;
122 #else
123 dsc->diff = -event->wheel.y;
124 #endif
125 break;
126 case SDL_MOUSEBUTTONDOWN:
127 if(event->button.button == SDL_BUTTON_MIDDLE) {
128 dsc->state = LV_INDEV_STATE_PRESSED;
129 }
130 break;
131 case SDL_MOUSEBUTTONUP:
132 if(event->button.button == SDL_BUTTON_MIDDLE) {
133 dsc->state = LV_INDEV_STATE_RELEASED;
134 }
135 break;
136 default:
137 break;
138 }
139 lv_indev_read(indev);
140 }
141
142 #endif /*LV_USE_SDL*/
143