calibration.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. #include <rtgui/rtgui.h>
  2. #include <rtgui/dc.h>
  3. #include <rtgui/rtgui_system.h>
  4. #include <rtgui/widgets/window.h>
  5. #include <rtgui/rtgui_app.h>
  6. #include "touch.h"
  7. #include "setup.h"
  8. #define CALIBRATION_STEP_LEFTTOP 0
  9. #define CALIBRATION_STEP_RIGHTTOP 1
  10. #define CALIBRATION_STEP_RIGHTBOTTOM 2
  11. #define CALIBRATION_STEP_LEFTBOTTOM 3
  12. #define CALIBRATION_STEP_CENTER 4
  13. #define TOUCH_WIN_UPDATE 1
  14. #define TOUCH_WIN_CLOSE 2
  15. #define CALIBRATION_WIDTH 15
  16. #define CALIBRATION_HEIGHT 15
  17. struct calibration_session
  18. {
  19. rt_uint8_t step;
  20. struct calibration_data data;
  21. rt_uint16_t width; rt_uint16_t height;
  22. rtgui_win_t* win;
  23. rt_device_t device;
  24. rt_thread_t tid;
  25. };
  26. static struct calibration_session* calibration_ptr = RT_NULL;
  27. static void calibration_data_post(rt_uint16_t x, rt_uint16_t y)
  28. {
  29. rt_kprintf("calibration_data_post x %d y %d\n", x, y);
  30. if (calibration_ptr != RT_NULL)
  31. {
  32. switch (calibration_ptr->step)
  33. {
  34. case CALIBRATION_STEP_LEFTTOP:
  35. calibration_ptr->data.min_x = x;
  36. calibration_ptr->data.min_y = y;
  37. break;
  38. case CALIBRATION_STEP_RIGHTTOP:
  39. calibration_ptr->data.max_x = x;
  40. calibration_ptr->data.min_y = (calibration_ptr->data.min_y + y)/2;
  41. break;
  42. case CALIBRATION_STEP_LEFTBOTTOM:
  43. calibration_ptr->data.min_x = (calibration_ptr->data.min_x + x)/2;
  44. calibration_ptr->data.max_y = y;
  45. break;
  46. case CALIBRATION_STEP_RIGHTBOTTOM:
  47. calibration_ptr->data.max_x = (calibration_ptr->data.max_x + x)/2;
  48. calibration_ptr->data.max_y = (calibration_ptr->data.max_y + y)/2;
  49. break;
  50. case CALIBRATION_STEP_CENTER:
  51. /* calibration done */
  52. {
  53. rt_uint16_t w, h;
  54. struct rtgui_event_command ecmd;
  55. RTGUI_EVENT_COMMAND_INIT(&ecmd);
  56. ecmd.wid = calibration_ptr->win;
  57. ecmd.command_id = TOUCH_WIN_CLOSE;
  58. /* calculate calibrated data */
  59. if (calibration_ptr->data.max_x > calibration_ptr->data.min_x)
  60. w = calibration_ptr->data.max_x - calibration_ptr->data.min_x;
  61. else
  62. w = calibration_ptr->data.min_x - calibration_ptr->data.max_x;
  63. w = (w/(calibration_ptr->width - 2 * CALIBRATION_WIDTH)) * CALIBRATION_WIDTH;
  64. if (calibration_ptr->data.max_y > calibration_ptr->data.min_y)
  65. h = calibration_ptr->data.max_y - calibration_ptr->data.min_y;
  66. else
  67. h = calibration_ptr->data.min_y - calibration_ptr->data.max_y;
  68. h = (h/(calibration_ptr->height - 2 * CALIBRATION_HEIGHT)) * CALIBRATION_HEIGHT;
  69. rt_kprintf("w: %d, h: %d\n", w, h);
  70. if (calibration_ptr->data.max_x > calibration_ptr->data.min_x)
  71. {
  72. calibration_ptr->data.min_x -= w;
  73. calibration_ptr->data.max_x += w;
  74. }
  75. else
  76. {
  77. calibration_ptr->data.min_x += w;
  78. calibration_ptr->data.max_x -= w;
  79. }
  80. if (calibration_ptr->data.max_y > calibration_ptr->data.min_y)
  81. {
  82. calibration_ptr->data.min_y -= h;
  83. calibration_ptr->data.max_y += h;
  84. }
  85. else
  86. {
  87. calibration_ptr->data.min_y += h;
  88. calibration_ptr->data.max_y -= h;
  89. }
  90. rt_kprintf("calibration data: (%d, %d), (%d, %d)\n",
  91. calibration_ptr->data.min_x,
  92. calibration_ptr->data.max_x,
  93. calibration_ptr->data.min_y,
  94. calibration_ptr->data.max_y);
  95. rtgui_send(calibration_ptr->tid, &ecmd.parent, sizeof(struct rtgui_event_command));
  96. }
  97. return;
  98. }
  99. calibration_ptr->step ++;
  100. /* post command event */
  101. {
  102. struct rtgui_event_command ecmd;
  103. RTGUI_EVENT_COMMAND_INIT(&ecmd);
  104. ecmd.wid = calibration_ptr->win;
  105. ecmd.command_id = TOUCH_WIN_UPDATE;
  106. rtgui_send(calibration_ptr->tid, &ecmd.parent, sizeof(struct rtgui_event_command));
  107. }
  108. }
  109. }
  110. rt_bool_t calibration_event_handler(struct rtgui_object* object, struct rtgui_event* event)
  111. {
  112. struct rtgui_widget *widget = RTGUI_WIDGET(object);
  113. switch (event->type)
  114. {
  115. case RTGUI_EVENT_PAINT:
  116. {
  117. struct rtgui_dc* dc;
  118. struct rtgui_rect rect;
  119. dc = rtgui_dc_begin_drawing(widget);
  120. if (dc == RT_NULL) break;
  121. /* get rect information */
  122. rtgui_widget_get_rect(widget, &rect);
  123. /* clear whole window */
  124. RTGUI_WIDGET_BACKGROUND(widget) = white;
  125. rtgui_dc_fill_rect(dc, &rect);
  126. /* reset color */
  127. RTGUI_WIDGET_BACKGROUND(widget) = green;
  128. RTGUI_WIDGET_FOREGROUND(widget) = black;
  129. switch (calibration_ptr->step)
  130. {
  131. case CALIBRATION_STEP_LEFTTOP:
  132. rtgui_dc_draw_hline(dc, 0, 2 * CALIBRATION_WIDTH, CALIBRATION_HEIGHT);
  133. rtgui_dc_draw_vline(dc, CALIBRATION_WIDTH, 0, 2 * CALIBRATION_HEIGHT);
  134. RTGUI_WIDGET_FOREGROUND(widget) = red;
  135. rtgui_dc_fill_circle(dc, CALIBRATION_WIDTH, CALIBRATION_HEIGHT, 4);
  136. break;
  137. case CALIBRATION_STEP_RIGHTTOP:
  138. rtgui_dc_draw_hline(dc, calibration_ptr->width - 2 * CALIBRATION_WIDTH,
  139. calibration_ptr->width, CALIBRATION_HEIGHT);
  140. rtgui_dc_draw_vline(dc, calibration_ptr->width - CALIBRATION_WIDTH, 0, 2 * CALIBRATION_HEIGHT);
  141. RTGUI_WIDGET_FOREGROUND(widget) = red;
  142. rtgui_dc_fill_circle(dc, calibration_ptr->width - CALIBRATION_WIDTH, CALIBRATION_HEIGHT, 4);
  143. break;
  144. case CALIBRATION_STEP_LEFTBOTTOM:
  145. rtgui_dc_draw_hline(dc, 0, 2 * CALIBRATION_WIDTH, calibration_ptr->height - CALIBRATION_HEIGHT);
  146. rtgui_dc_draw_vline(dc, CALIBRATION_WIDTH, calibration_ptr->height - 2 * CALIBRATION_HEIGHT, calibration_ptr->height);
  147. RTGUI_WIDGET_FOREGROUND(widget) = red;
  148. rtgui_dc_fill_circle(dc, CALIBRATION_WIDTH, calibration_ptr->height - CALIBRATION_HEIGHT, 4);
  149. break;
  150. case CALIBRATION_STEP_RIGHTBOTTOM:
  151. rtgui_dc_draw_hline(dc, calibration_ptr->width - 2 * CALIBRATION_WIDTH,
  152. calibration_ptr->width, calibration_ptr->height - CALIBRATION_HEIGHT);
  153. rtgui_dc_draw_vline(dc, calibration_ptr->width - CALIBRATION_WIDTH, calibration_ptr->height - 2 * CALIBRATION_HEIGHT, calibration_ptr->height);
  154. RTGUI_WIDGET_FOREGROUND(widget) = red;
  155. rtgui_dc_fill_circle(dc, calibration_ptr->width - CALIBRATION_WIDTH, calibration_ptr->height - CALIBRATION_HEIGHT, 4);
  156. break;
  157. case CALIBRATION_STEP_CENTER:
  158. rtgui_dc_draw_hline(dc, calibration_ptr->width/2 - CALIBRATION_WIDTH, calibration_ptr->width/2 + CALIBRATION_WIDTH, calibration_ptr->height/2);
  159. rtgui_dc_draw_vline(dc, calibration_ptr->width/2, calibration_ptr->height/2 - CALIBRATION_HEIGHT, calibration_ptr->height/2 + CALIBRATION_HEIGHT);
  160. RTGUI_WIDGET_FOREGROUND(widget) = red;
  161. rtgui_dc_fill_circle(dc, calibration_ptr->width/2, calibration_ptr->height/2, 4);
  162. break;
  163. }
  164. rtgui_dc_end_drawing(dc);
  165. }
  166. break;
  167. case RTGUI_EVENT_COMMAND:
  168. {
  169. struct rtgui_event_command* ecmd = (struct rtgui_event_command*)event;
  170. switch (ecmd->command_id)
  171. {
  172. case TOUCH_WIN_UPDATE:
  173. rtgui_widget_update(widget);
  174. break;
  175. case TOUCH_WIN_CLOSE:
  176. rtgui_win_close(RTGUI_WIN(widget));
  177. break;
  178. }
  179. }
  180. return RT_TRUE;
  181. default:
  182. rtgui_win_event_handler(RTGUI_OBJECT(widget), event);
  183. }
  184. return RT_FALSE;
  185. }
  186. void calibration_entry(void* parameter)
  187. {
  188. rt_device_t device;
  189. struct rtgui_rect rect;
  190. struct rtgui_app* application;
  191. struct setup_items setup;
  192. device = rt_device_find("touch");
  193. if (device == RT_NULL) return; /* no this device */
  194. calibration_ptr = (struct calibration_session*)
  195. rt_malloc(sizeof(struct calibration_session));
  196. rt_memset(calibration_ptr, 0, sizeof(struct calibration_data));
  197. calibration_ptr->device = device;
  198. calibration_ptr->tid = rt_thread_self();
  199. rt_device_control(calibration_ptr->device, RT_TOUCH_CALIBRATION,
  200. (void*)calibration_data_post);
  201. rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), &rect);
  202. /* set screen rect */
  203. calibration_ptr->width = rect.x2;
  204. calibration_ptr->height = rect.y2;
  205. application = rtgui_app_create(rt_thread_self(), "calibration");
  206. if (application != RT_NULL)
  207. {
  208. /* create calibration window */
  209. calibration_ptr->win = rtgui_win_create(RT_NULL,
  210. "calibration", &rect,
  211. RTGUI_WIN_STYLE_NO_TITLE | RTGUI_WIN_STYLE_NO_BORDER |
  212. RTGUI_WIN_STYLE_ONTOP | RTGUI_WIN_STYLE_DESTROY_ON_CLOSE);
  213. if (calibration_ptr->win != RT_NULL)
  214. {
  215. rtgui_object_set_event_handler(RTGUI_OBJECT(calibration_ptr->win),
  216. calibration_event_handler);
  217. rtgui_win_show(calibration_ptr->win, RT_TRUE);
  218. }
  219. rtgui_app_destroy(application);
  220. }
  221. /* set calibration data */
  222. rt_device_control(calibration_ptr->device, RT_TOUCH_CALIBRATION_DATA,
  223. &calibration_ptr->data);
  224. //save setup
  225. setup.touch_min_x = calibration_ptr->data.min_x;
  226. setup.touch_max_x = calibration_ptr->data.max_x;
  227. setup.touch_min_y = calibration_ptr->data.min_y;
  228. setup.touch_max_y = calibration_ptr->data.max_y;
  229. setup_save(&setup);
  230. /* recover to normal */
  231. rt_device_control(calibration_ptr->device, RT_TOUCH_NORMAL, RT_NULL);
  232. /* release memory */
  233. rt_free(calibration_ptr);
  234. calibration_ptr = RT_NULL;
  235. }
  236. void calibration_init(void)
  237. {
  238. rt_thread_t tid;
  239. struct setup_items setup;
  240. if(setup_load(&setup) == RT_EOK)
  241. {
  242. struct calibration_data data;
  243. rt_device_t device;
  244. data.min_x = setup.touch_min_x;
  245. data.max_x = setup.touch_max_x;
  246. data.min_y = setup.touch_min_y;
  247. data.max_y = setup.touch_max_y;
  248. device = rt_device_find("touch");
  249. if(device != RT_NULL)
  250. rt_device_control(device, RT_TOUCH_CALIBRATION_DATA, &data);
  251. return;
  252. }
  253. tid = rt_thread_create("cali", calibration_entry, RT_NULL, 1024, 20, 20);
  254. if (tid != RT_NULL)
  255. rt_thread_startup(tid);
  256. }
  257. #ifdef RT_USING_FINSH
  258. #include <finsh.h>
  259. void calibration(void)
  260. {
  261. calibration_init();
  262. }
  263. FINSH_FUNCTION_EXPORT(calibration, perform touch calibration);
  264. #endif