TouchScreen.c
上传用户:lqx1163
上传日期:2014-08-13
资源大小:9183k
文件大小:207k
源码类别:

MTK

开发平台:

C/C++

  1. /*****************************************************************************
  2. *  Copyright Statement:
  3. *  --------------------
  4. *  This software is protected by Copyright and the information contained
  5. *  herein is confidential. The software may not be copied and the information
  6. *  contained herein may not be used or disclosed except with the written
  7. *  permission of MediaTek Inc. (C) 2005
  8. *
  9. *  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  10. *  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  11. *  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
  12. *  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  13. *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  14. *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  15. *  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  16. *  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  17. *  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
  18. *  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
  19. *  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
  20. *  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
  21. *
  22. *  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
  23. *  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  24. *  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  25. *  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
  26. *  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
  27. *
  28. *  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
  29. *  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
  30. *  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
  31. *  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
  32. *  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
  33. *
  34. *****************************************************************************/
  35. /*****************************************************************************
  36.  *
  37.  * Filename:
  38.  * ---------
  39.  *   TouchScreen.c
  40.  *
  41.  * Project:
  42.  * --------
  43.  *   MAUI
  44.  *
  45.  * Description:
  46.  * ------------
  47.  *   Low-level Touch Screen API - interface between driver or PC simulator
  48.  *
  49.  * Author:
  50.  * -------
  51.  * -------
  52.  *
  53.  *============================================================================
  54.  *             HISTORY
  55.  * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
  56.  *------------------------------------------------------------------------------
  57.  * removed!
  58.  *
  59.  * removed!
  60.  * removed!
  61.  * removed!
  62.  *
  63.  * removed!
  64.  * removed!
  65.  * removed!
  66.  *
  67.  * removed!
  68.  * removed!
  69.  * removed!
  70.  *
  71.  * removed!
  72.  * removed!
  73.  * removed!
  74.  *
  75.  * removed!
  76.  * removed!
  77.  * removed!
  78.  *
  79.  * removed!
  80.  * removed!
  81.  * removed!
  82.  *
  83.  * removed!
  84.  * removed!
  85.  * removed!
  86.  *
  87.  * removed!
  88.  * removed!
  89.  * removed!
  90.  *
  91.  * removed!
  92.  * removed!
  93.  * removed!
  94.  *
  95.  * removed!
  96.  * removed!
  97.  * removed!
  98.  *
  99.  * removed!
  100.  * removed!
  101.  * removed!
  102.  *
  103.  * removed!
  104.  * removed!
  105.  * removed!
  106.  *
  107.  * removed!
  108.  * removed!
  109.  * removed!
  110.  *
  111.  * removed!
  112.  * removed!
  113.  * removed!
  114.  *
  115.  * removed!
  116.  * removed!
  117.  * removed!
  118.  *
  119.  * removed!
  120.  * removed!
  121.  * removed!
  122.  *
  123.  * removed!
  124.  * removed!
  125.  * removed!
  126.  *
  127.  * removed!
  128.  * removed!
  129.  * removed!
  130.  *
  131.  * removed!
  132.  * removed!
  133.  * removed!
  134.  *
  135.  * removed!
  136.  * removed!
  137.  * removed!
  138.  *
  139.  * removed!
  140.  * removed!
  141.  * removed!
  142.  *
  143.  * removed!
  144.  * removed!
  145.  * removed!
  146.  *
  147.  * removed!
  148.  * removed!
  149.  * removed!
  150.  *
  151.  * removed!
  152.  * removed!
  153.  * removed!
  154.  *
  155.  * removed!
  156.  * removed!
  157.  * removed!
  158.  *
  159.  * removed!
  160.  * removed!
  161.  * removed!
  162.  *
  163.  * removed!
  164.  * removed!
  165.  * removed!
  166.  *
  167.  * removed!
  168.  * removed!
  169.  * removed!
  170.  *
  171.  *------------------------------------------------------------------------------
  172.  * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
  173.  *============================================================================
  174.  ****************************************************************************/
  175. #include "MMI_features.h"
  176. /* Save stroke data in filesystem for analysis of recognition rate */
  177. #undef MMI_PEN_SAVE_STROKE_IN_FILE
  178. /*****************************************************************************
  179.  * In case that handwriting area is overlapped with an editor, we need to 
  180.  * define a way to move cursor inside the editor.
  181.  *
  182.  * Three approaches are supported:
  183.  *
  184.  * 1. !defined(MMI_PEN_SUPPORT_STROKE_LONGTAP) and single-block --> (MMI_PEN_STROKE_MIN_OFFSET > 0)
  185.  *
  186.  * In the first stroke (after mmi_pen_begin_strokes_of_character()), 
  187.  * stroke down in handwriting area is translated to Pen Down event first until pen is 
  188.  * moved across predefined distance MMI_PEN_STROKE_MIN_OFFSET.
  189.  *
  190.  * For example, driver events are converted to MMI events in the first stroke like:
  191.  *
  192.  * STROKE_DOWN, STROKE_UP --> MMI_PEN_EVENT_DOWN, MMI_PEN_EVENT_UP
  193.  *       (stroke buffer is empty, handwriting area is reset to default)
  194.  *
  195.  * STROKE_DOWN, STROKE_MOVE (< MMI_PEN_STROKE_MIN_OFFSET), STROKE_UP --> 
  196.  *       MMI_PEN_EVENT_DOWN, MMI_PEN_EVENT_UP
  197.  *       (the STROKE_MOVE before STROKE_UP is dropped, 
  198.  *        stroke buffer is empty, handwriting area is reset to default)
  199.  *
  200.  * STROKE_DOWN, STROKE_MOVE (> MMI_PEN_STROKE_MIN_OFFSET), STROKE_UP -->
  201.  *       MMI_PEN_EVENT_DOWN, MMI_PEN_EVENT_ABORT, MMI_PEN_STROKE_DOWN, 
  202.  *                           MMI_PEN_STROKE_MOVE, MMI_PEN_STROKE_UP
  203.  *       (The original Pen Down event is aborted, and the first stroke is created)
  204.  *
  205.  * 2. !defined(MMI_PEN_SUPPORT_STROKE_LONGTAP) and multi-block --> 
  206.  * 
  207.  * Handwriting area and non-handwriting area are not overlapped. This is the simplest case.
  208.  *
  209.  * Unnecessary to translate driver pen events.
  210.  *
  211.  * 3. defined(MMI_PEN_SUPPORT_STROKE_LONGTAP) --> (MMI_PEN_STROKE_MIN_OFFSET == 0)
  212.  *
  213.  * In the first stroke (after mmi_pen_begin_strokes_of_character()), 
  214.  * stroke down are translated to Stroke Down event directly. However, when pen stays at the 
  215.  * pen down position within MMI_PEN_SKIP_STROKE_LONGTAP_OFFSET after MMI_PEN_STROKE_LONGTAP_TIME,
  216.  * Stroke LongTap event is generated. Editor will interpret the subsequent 
  217.  * Stroke Move events as editor cursor control commands.
  218.  *
  219.  * For example, driver events are converted to MMI events in the first stroke like:
  220.  *
  221.  * STROKE_DOWN, STROKE_UP --> MMI_PEN_STROKE_DOWN, MMI_PEN_STROKE_UP
  222.  *       (The first stroke is created, and stroke buffer is not empty.)
  223.  *
  224.  * STROKE_DOWN, STROKE_MOVE, STROKE_UP --> 
  225.  *       MMI_PEN_STROKE_DOWN, MMI_PEN_STROKE_MOVE, MMI_PEN_STROKE_UP
  226.  *       (The first stroke is created, and stroke buffer is not empty.)
  227.  *
  228.  * STROKE_DOWN, STROKE_MOVE (1st), STROKE_LONGTAP, STROKE_MOVE (2nd), STROKE_UP -->
  229.  *       MMI_PEN_STROKE_DOWN, MMI_PEN_STROKE_MOVE (1st), MMI_PEN_STROKE_LONGTAP, 
  230.  *       MMI_PEN_STROKE_MOVE (2nd), MMI_PEN_STROKE_UP
  231.  *       (The first stroke is aborted, handwriting area is reset to default, 
  232.  *        Stroke buffer is cleared.)
  233.  *       (NOTE: after STROKE_LONGTAP, we decrease the sampling rate to MMI_PEN_SAMPLING_PERIOD_1)
  234.  *
  235.  * Note that after the first stroke is created, STROKE_LONGTAP events generated by driver are ignored.
  236.  *
  237.  ****************************************************************************/
  238. #if ( defined(__MMI_TOUCH_SCREEN__) || defined(__MMI_HANDWRITING_PAD__)) && !defined(__MTK_TARGET__)
  239. /*****************************************************************************
  240.  *
  241.  * WIN32 integration 
  242.  * PC Simulator & MODIS
  243.  *
  244.  ****************************************************************************/
  245. #include "stdC.h"
  246. #include "PixtelDataTypes.h"
  247. #include "TimerEvents.h"
  248. #include "KeyBrd.h"
  249. #include "FrameworkStruct.h"
  250. #include "EventsGprot.h"
  251. #include "EventsDcl.h"
  252. #include "EventsDef.h"
  253. #include "gui_data_types.h"
  254. #include "gui.h"
  255. #include "IdleAppProt.h"
  256. #include "kal_non_specific_general_types.h"
  257. #include "TouchScreenGprot.h"
  258. #include "DebugInitDef.h"
  259. #include "lcd_sw_rnd.h" /* LCD width/height */
  260. #include "time.h"       /* time() */
  261. #include "gdi_include.h"
  262. #include "ScreenRotationGprot.h"
  263. #include "touch_panel_custom.h" /* get handwriting pad setting */
  264. #if !defined(MMI_ON_WIN32)
  265. static void mmi_pen_MODIS_start_timer(void);
  266. static void mmi_pen_MODIS_flush_queue(void);
  267. #endif /* !defined(MMI_ON_WIN32) */ 
  268. /***************************************************************************** 
  269. * Define
  270. *****************************************************************************/
  271. #define MMI_PEN_MAX_HANDWRITING_REGION (3)
  272. #undef MMI_PEN_UNIT_TEST
  273. /***************************************************************************** 
  274. * Typedef 
  275. *****************************************************************************/
  276. typedef struct
  277. {
  278.     /* mmi_pen_block() & mmi_pen_unblock() */
  279.     U32 is_blocked:1;
  280.     /* mmi_pen_enable() & mmi_pen_disable() */
  281.     U32 is_enabled:1;
  282.     /* mmi_pen_reset() set 'is_pen_down' to 0 */
  283.     U32 is_pen_down:1;
  284.     /* The current pen down/move/up is a stroke */
  285.     U32 is_stroke_event:1;
  286.     /* Checking offset with g_pen_stroke_min_offset */
  287.     U32 is_pending_stroke_event:1;
  288.     /* A first stroke is created. This flag is cleared in mmi_pen_begin_strokes_of_character() */
  289.     U32 is_stroke_created:1;
  290.     /* Stroke LongTap event is generated. */
  291.     U32 is_stroke_longtap_event_generated:1;
  292.     /* Set in mmi_pen_end_strokes_of_character(), 
  293.        do not enqueue incoming strokes until mmi_pen_begin_strokes_of_character() is invoked again */
  294.     U32 is_all_stroke_finished:1;
  295.     /* wait for 1: pen long-tap 0: pen repeat (event-based) */
  296.     U32 is_waiting_long_tap_event:1;
  297.     /* 
  298.      * Set by mmi_pen_change_handwriting_area() and mmi_pen_stop_capture_strokes().
  299.      * Close stroke and reset touch screen when pen is up. 
  300.      */
  301.     U32 reset_stroke_on_pen_up:1;
  302.     /* The position where pen is tapped down */
  303.     mmi_pen_point_struct pen_down_pos;
  304.     /* Block index of handwriting area */
  305.     S32 stroke_down_block_index;
  306.     /* The current pen position */
  307.     mmi_pen_point_struct pen_current_pos;
  308.     /* For Pen Repeat */
  309.     mmi_pen_point_struct pen_repeat_origin_pos;
  310.     /* For stroke */
  311.     S32 num_points_queued;
  312. } mmi_pen_context_struct;
  313. /***************************************************************************** 
  314. * Local Variable
  315. *****************************************************************************/
  316. static mmi_pen_context_struct g_pen_cntx;
  317. static mmi_pen_hdlr g_pen_event_table[MMI_PEN_EVENT_TYPE_MAX];
  318. static mmi_pen_hdlr g_pen_stroke_table[MMI_PEN_STROKE_TYPE_MAX];
  319. static void (*g_pen_stroke_pre_move) (void);
  320. static void (*g_pen_stroke_post_move) (void);
  321. static int g_pen_num_stroke_area;   /* 0 if stroke area is not enabled */
  322. static mmi_pen_handwriting_area_struct g_pen_stroke_areas[MMI_PEN_MAX_HANDWRITING_REGION];
  323. static mmi_pen_handwriting_area_struct g_pen_ext_stroke_area;
  324. static int g_pen_stroke_min_offset;
  325. static S32 g_pen_stroke_max_points;
  326. static mmi_pen_point_struct *g_pen_stroke_points;
  327. /***************************************************************************** 
  328. * Local Function
  329. *****************************************************************************/
  330. static void mmi_pen_MODIS_tp_ind(void *);
  331. /*****************************************************************************
  332.  * FUNCTION
  333.  *  mmi_pen_simulator_fix_point_bound
  334.  * DESCRIPTION
  335.  *  
  336.  * PARAMETERS
  337.  *  x       [IN/OUT]     
  338.  *  y       [INT/OUT]     
  339.  * RETURNS
  340.  *  void
  341.  *****************************************************************************/
  342. static void mmi_pen_simulator_fix_point_bound(S16 *x, S16 *y, MMI_BOOL check_multi_block)
  343. {
  344.     /*----------------------------------------------------------------*/
  345.     /* Local Variables                                                */
  346.     /*----------------------------------------------------------------*/
  347.     mmi_pen_handwriting_area_struct *block;
  348.     /*----------------------------------------------------------------*/
  349.     /* Code Body                                                      */
  350.     /*----------------------------------------------------------------*/
  351.     if (*x < 0)
  352.     {
  353.         *x = 0;
  354.     }
  355.     else if (*x >= UI_device_width)
  356.     {
  357.         *x = UI_device_width - 1;
  358.     }
  359.     if (*y < 0)
  360.     {
  361.         *y = 0;
  362.     }
  363.     else if (*y >= UI_device_height)
  364.     {
  365.         *y = UI_device_height - 1;
  366.     }
  367.     if (check_multi_block)
  368.     {
  369.         MMI_ASSERT(g_pen_cntx.stroke_down_block_index >= 0 &&
  370.                    g_pen_cntx.stroke_down_block_index < g_pen_num_stroke_area);
  371.         block = &g_pen_stroke_areas[g_pen_cntx.stroke_down_block_index];
  372.         
  373.         if (*x < block->x1)
  374.         {
  375.             *x = block->x1;
  376.         }
  377.         else if (*x > block->x2)
  378.         {
  379.             *x = block->x2;
  380.         }
  381.         
  382.         if (*y < block->y1)
  383.         {
  384.             *y = block->y1;
  385.         }
  386.         else if (*y > block->y2)
  387.         {
  388.             *y = block->y2;
  389.         }
  390.     }
  391. }
  392. /*****************************************************************************
  393.  * FUNCTION
  394.  *  mmi_pen_simulator_pixel_diff
  395.  * DESCRIPTION
  396.  *  
  397.  * PARAMETERS
  398.  *  pos1        [IN]        
  399.  *  pos2        [IN]        
  400.  * RETURNS
  401.  *  
  402.  *****************************************************************************/
  403. static S16 mmi_pen_simulator_pixel_diff(mmi_pen_point_struct pos1, mmi_pen_point_struct pos2)
  404. {
  405.     /*----------------------------------------------------------------*/
  406.     /* Local Variables                                                */
  407.     /*----------------------------------------------------------------*/
  408.     S16 diff_x = pos1.x - pos2.x;
  409.     S16 diff_y = pos1.y - pos2.y;
  410.     /*----------------------------------------------------------------*/
  411.     /* Code Body                                                      */
  412.     /*----------------------------------------------------------------*/
  413.     if (diff_x < 0)
  414.     {
  415.         diff_x = -diff_x;
  416.     }
  417.     if (diff_y < 0)
  418.     {
  419.         diff_y = -diff_y;
  420.     }
  421.     return diff_x + diff_y;
  422. }
  423. /*****************************************************************************
  424.  * FUNCTION
  425.  *  mmi_pen_simulator_in_stroke_area
  426.  * DESCRIPTION
  427.  *  
  428.  * PARAMETERS
  429.  *  x       [IN]        
  430.  *  y       [IN]        
  431.  * RETURNS
  432.  *  The index of block. 0 for block-0 or extended area, -1 if not found.
  433.  *****************************************************************************/
  434. static S32 mmi_pen_simulator_in_stroke_area(S16 x, S16 y)
  435. {
  436.     /*----------------------------------------------------------------*/
  437.     /* Local Variables                                                */
  438.     /*----------------------------------------------------------------*/
  439.     int i;
  440.     /*----------------------------------------------------------------*/
  441.     /* Code Body                                                      */
  442.     /*----------------------------------------------------------------*/
  443.     if (g_pen_cntx.is_stroke_created &&
  444.         (g_pen_ext_stroke_area.x2 >= 0) && /* Test if the extended handwriting area is enabled */
  445.         x >= g_pen_ext_stroke_area.x1 && x <= g_pen_ext_stroke_area.x2 &&
  446.         y >= g_pen_ext_stroke_area.y1 && y <= g_pen_ext_stroke_area.y2)
  447.     {
  448.         return 0;
  449.     }
  450.     for (i = 0; i < g_pen_num_stroke_area; i++)
  451.     {
  452.         if (x >= g_pen_stroke_areas[i].x1 && x <= g_pen_stroke_areas[i].x2 &&
  453.             y >= g_pen_stroke_areas[i].y1 && y <= g_pen_stroke_areas[i].y2)
  454.         {
  455.             return i;
  456.         }
  457.     }
  458.     return -1;
  459. }
  460. /*****************************************************************************
  461.  * FUNCTION
  462.  *  mmi_pen_simulator_push_stroke_point
  463.  * DESCRIPTION
  464.  *  
  465.  * PARAMETERS
  466.  *  x       [IN]        
  467.  *  y       [IN]        
  468.  * RETURNS
  469.  *  void
  470.  *****************************************************************************/
  471. static void mmi_pen_simulator_push_stroke_point(S16 x, S16 y)
  472. {
  473.     /*----------------------------------------------------------------*/
  474.     /* Local Variables                                                */
  475.     /*----------------------------------------------------------------*/
  476.     /*----------------------------------------------------------------*/
  477.     /* Code Body                                                      */
  478.     /*----------------------------------------------------------------*/
  479.     if (g_pen_cntx.num_points_queued >= g_pen_stroke_max_points - 2)
  480.     {
  481.         return;
  482.     }
  483.     g_pen_stroke_points[g_pen_cntx.num_points_queued].x = x;
  484.     g_pen_stroke_points[g_pen_cntx.num_points_queued].y = y;
  485.     g_pen_cntx.num_points_queued++;
  486. }
  487. /*****************************************************************************
  488.  * FUNCTION
  489.  *  mmi_pen_simulator_push_stroke_end
  490.  * DESCRIPTION
  491.  *  
  492.  * PARAMETERS
  493.  *  void
  494.  * RETURNS
  495.  *  void
  496.  *****************************************************************************/
  497. static void mmi_pen_simulator_push_stroke_end(void)
  498. {
  499.     /*----------------------------------------------------------------*/
  500.     /* Local Variables                                                */
  501.     /*----------------------------------------------------------------*/
  502.     /*----------------------------------------------------------------*/
  503.     /* Code Body                                                      */
  504.     /*----------------------------------------------------------------*/
  505.     if (g_pen_cntx.num_points_queued >= g_pen_stroke_max_points - 1)
  506.     {
  507.         MMI_ASSERT(0);  /* queue full */
  508.         return;
  509.     }
  510. #if defined(__MMI_HANWANG__)
  511.     g_pen_stroke_points[g_pen_cntx.num_points_queued].x = -1;
  512.     g_pen_stroke_points[g_pen_cntx.num_points_queued].y = 0;
  513. #elif defined(__MMI_PENPOWER__)
  514.     g_pen_stroke_points[g_pen_cntx.num_points_queued].x = -1;
  515.     g_pen_stroke_points[g_pen_cntx.num_points_queued].y = -1;
  516. #else 
  517.     g_pen_stroke_points[g_pen_cntx.num_points_queued].x = -1;
  518.     g_pen_stroke_points[g_pen_cntx.num_points_queued].y = 0;
  519. #endif 
  520.     g_pen_cntx.num_points_queued++;
  521. }
  522. /*****************************************************************************
  523.  * FUNCTION
  524.  *  mmi_pen_simulator_push_char_end
  525.  * DESCRIPTION
  526.  *  
  527.  * PARAMETERS
  528.  *  void
  529.  * RETURNS
  530.  *  void
  531.  *****************************************************************************/
  532. static void mmi_pen_simulator_push_char_end(void)
  533. {
  534.     /*----------------------------------------------------------------*/
  535.     /* Local Variables                                                */
  536.     /*----------------------------------------------------------------*/
  537.     /*----------------------------------------------------------------*/
  538.     /* Code Body                                                      */
  539.     /*----------------------------------------------------------------*/
  540.     if (g_pen_cntx.num_points_queued >= g_pen_stroke_max_points)
  541.     {
  542.         MMI_ASSERT(0);  /* queue full */
  543.         return;
  544.     }
  545. #if defined(__MMI_HANWANG__)
  546.     g_pen_stroke_points[g_pen_cntx.num_points_queued].x = -1;
  547.     g_pen_stroke_points[g_pen_cntx.num_points_queued].y = -1;
  548. #elif defined(__MMI_PENPOWER__)
  549.     g_pen_stroke_points[g_pen_cntx.num_points_queued].x = -1;
  550.     g_pen_stroke_points[g_pen_cntx.num_points_queued].y = 0;
  551. #else 
  552.     g_pen_stroke_points[g_pen_cntx.num_points_queued].x = -1;
  553.     g_pen_stroke_points[g_pen_cntx.num_points_queued].y = -1;
  554. #endif 
  555.     g_pen_cntx.num_points_queued++;
  556. }
  557. /*****************************************************************************
  558.  * FUNCTION
  559.  *  mmi_pen_simulator_repeat_hdlr
  560.  * DESCRIPTION
  561.  *  
  562.  * PARAMETERS
  563.  *  void
  564.  * RETURNS
  565.  *  void
  566.  *****************************************************************************/
  567. static void mmi_pen_simulator_repeat_hdlr(void)
  568. {
  569.     /*----------------------------------------------------------------*/
  570.     /* Local Variables                                                */
  571.     /*----------------------------------------------------------------*/
  572.     /*----------------------------------------------------------------*/
  573.     /* Code Body                                                      */
  574.     /*----------------------------------------------------------------*/
  575.     MMI_ASSERT(g_pen_cntx.is_enabled && g_pen_cntx.is_pen_down);
  576.     if (g_pen_cntx.is_waiting_long_tap_event)
  577.     {
  578.         if (g_pen_event_table[MMI_PEN_EVENT_LONG_TAP])
  579.         {
  580.             (g_pen_event_table[MMI_PEN_EVENT_LONG_TAP]) (g_pen_cntx.pen_down_pos);
  581.         }
  582.         g_pen_cntx.is_waiting_long_tap_event = 0;
  583.     }
  584.     else
  585.     {
  586.         if (g_pen_event_table[MMI_PEN_EVENT_REPEAT])
  587.         {
  588.             (g_pen_event_table[MMI_PEN_EVENT_REPEAT]) (g_pen_cntx.pen_repeat_origin_pos);
  589.         }
  590.     }
  591.     /* touch screen might be disabled/reset inside pen handler */
  592.     if (g_pen_cntx.is_enabled && g_pen_cntx.is_pen_down)
  593.     {
  594.         gui_start_timer(MMI_PEN_REPEAT_TIME * 10, mmi_pen_simulator_repeat_hdlr);
  595.     }
  596. }
  597. /*****************************************************************************
  598.  * FUNCTION
  599.  *  mmi_pen_simulator_stroke_longtap_hdlr
  600.  * DESCRIPTION
  601.  *  
  602.  * PARAMETERS
  603.  *  void
  604.  * RETURNS
  605.  *  void
  606.  *****************************************************************************/
  607. static void mmi_pen_simulator_stroke_longtap_hdlr(void)
  608. {
  609.     /*----------------------------------------------------------------*/
  610.     /* Local Variables                                                */
  611.     /*----------------------------------------------------------------*/
  612.     /*----------------------------------------------------------------*/
  613.     /* Code Body                                                      */
  614.     /*----------------------------------------------------------------*/
  615.     MMI_ASSERT(g_pen_cntx.is_enabled && g_pen_cntx.is_pen_down && g_pen_cntx.is_stroke_event);
  616.     g_pen_cntx.is_stroke_longtap_event_generated = 1;
  617.     if (g_pen_stroke_table[MMI_PEN_STROKE_LONGTAP])
  618.     {
  619.         (g_pen_stroke_table[MMI_PEN_STROKE_LONGTAP]) (g_pen_cntx.pen_current_pos);
  620.     }
  621. }
  622. /*****************************************************************************
  623.  * FUNCTION
  624.  *  mmi_pen_simulator_button_down_hdlr
  625.  * DESCRIPTION
  626.  *  
  627.  * PARAMETERS
  628.  *  x       [IN]        
  629.  *  y       [IN]        
  630.  * RETURNS
  631.  *  void
  632.  *****************************************************************************/
  633. void mmi_pen_simulator_button_down_hdlr(S16 x, S16 y)
  634. {
  635.     /*----------------------------------------------------------------*/
  636.     /* Local Variables                                                */
  637.     /*----------------------------------------------------------------*/
  638.     mmi_pen_point_struct pos;
  639.     /*----------------------------------------------------------------*/
  640.     /* Code Body                                                      */
  641.     /*----------------------------------------------------------------*/
  642.     if (!g_pen_cntx.is_enabled || g_pen_cntx.is_all_stroke_finished)
  643.     {
  644.         return;
  645.     }
  646.     MMI_DBG_ASSERT(!g_pen_cntx.is_pen_down);
  647.     mmi_pen_simulator_fix_point_bound(&x, &y, MMI_FALSE);
  648.     pos.x = x;
  649.     pos.y = y;
  650.     g_pen_cntx.pen_down_pos = g_pen_cntx.pen_current_pos = g_pen_cntx.pen_repeat_origin_pos = pos;
  651.     g_pen_cntx.is_pen_down = 1;
  652.     g_pen_cntx.is_stroke_event = 0;
  653.     g_pen_cntx.is_pending_stroke_event = 0;
  654.     g_pen_cntx.is_stroke_longtap_event_generated = 0;
  655.     /* Not reset is_stroke_created */
  656.     g_pen_cntx.is_waiting_long_tap_event = 0;
  657.     if ((g_pen_cntx.stroke_down_block_index = mmi_pen_simulator_in_stroke_area(x, y)) >= 0)
  658.     {
  659.         if (!g_pen_cntx.is_stroke_created && g_pen_stroke_min_offset > 0)
  660.         {
  661.             g_pen_cntx.is_pending_stroke_event = 1;
  662.             /* Fire pen down event. For example, it will display key down on virtual keyboard */
  663.             if (g_pen_event_table[MMI_PEN_EVENT_DOWN])
  664.             {
  665.                 (g_pen_event_table[MMI_PEN_EVENT_DOWN]) (pos);
  666.             }
  667.         }
  668.         else
  669.         {
  670.             if (!g_pen_cntx.is_stroke_created) /* StrokeLongTap is used in the first stroke only */
  671.             {
  672.                 gui_start_timer(MMI_PEN_STROKE_LONGTAP_TIME * 10, mmi_pen_simulator_stroke_longtap_hdlr);
  673.             }
  674.             
  675.             g_pen_cntx.is_stroke_event = 1;
  676.             g_pen_cntx.is_stroke_created = 1;
  677.             if (g_pen_stroke_table[MMI_PEN_STROKE_DOWN])
  678.             {
  679.                 (g_pen_stroke_table[MMI_PEN_STROKE_DOWN]) (pos);
  680.             }
  681.             /* Put stroke point after stroke down handler because multi-block handwriting may invoke
  682.              * mmi_pen_begin_strokes_of_character() and mmi_pen_end_strokes_of_character() in 
  683.              * Stroke Down handler.
  684.              */
  685.             if (g_pen_cntx.is_enabled && g_pen_cntx.is_pen_down && g_pen_stroke_max_points > 0)
  686.             {
  687.                 mmi_pen_simulator_push_stroke_point(x, y);
  688.             }
  689.         }
  690.     }
  691.     else
  692.     {
  693.         /* Note that Pen Down handler might call mmi_pen_reset() */
  694.         if (g_pen_event_table[MMI_PEN_EVENT_DOWN])
  695.         {
  696.             (g_pen_event_table[MMI_PEN_EVENT_DOWN]) (pos);
  697.         }
  698.         /* touch screen might be disabled inside pen handler */
  699.         if (g_pen_cntx.is_enabled && g_pen_cntx.is_pen_down)
  700.         {
  701.             g_pen_cntx.is_waiting_long_tap_event = 1;
  702.             gui_start_timer(MMI_PEN_REPEAT_TIME * 10, mmi_pen_simulator_repeat_hdlr);
  703.         }
  704.     }
  705. }
  706. /*****************************************************************************
  707.  * FUNCTION
  708.  *  mmi_pen_simulator_button_move_hdlr
  709.  * DESCRIPTION
  710.  *  
  711.  * PARAMETERS
  712.  *  x       [IN]        
  713.  *  y       [IN]        
  714.  * RETURNS
  715.  *  void
  716.  *****************************************************************************/
  717. void mmi_pen_simulator_button_move_hdlr(S16 x, S16 y)
  718. {
  719.     /*----------------------------------------------------------------*/
  720.     /* Local Variables                                                */
  721.     /*----------------------------------------------------------------*/
  722.     mmi_pen_point_struct pos;
  723.     BOOL restart_repeat_timer = MMI_FALSE;
  724.     /*----------------------------------------------------------------*/
  725.     /* Code Body                                                      */
  726.     /*----------------------------------------------------------------*/
  727.     if (!g_pen_cntx.is_enabled || !g_pen_cntx.is_pen_down)
  728.     {
  729.         return;
  730.     }
  731.     mmi_pen_simulator_fix_point_bound(&x, &y, g_pen_cntx.is_stroke_event && (g_pen_num_stroke_area > 1));
  732.     pos.x = x;
  733.     pos.y = y;
  734.     g_pen_cntx.pen_current_pos = pos;
  735.     if (g_pen_cntx.is_pending_stroke_event)
  736.     {
  737.         if (mmi_pen_simulator_pixel_diff(pos, g_pen_cntx.pen_down_pos) > g_pen_stroke_min_offset)
  738.         {
  739.             g_pen_cntx.is_pending_stroke_event = 0;
  740.             g_pen_cntx.is_stroke_event = 1;
  741.             g_pen_cntx.is_stroke_created = 1;
  742.             /* Abort previous pen down event */
  743.             if (g_pen_event_table[MMI_PEN_EVENT_ABORT])
  744.             {
  745.                 (g_pen_event_table[MMI_PEN_EVENT_ABORT]) (pos);
  746.             }
  747.             mmi_pen_simulator_push_stroke_point(g_pen_cntx.pen_down_pos.x, g_pen_cntx.pen_down_pos.y);
  748.             mmi_pen_simulator_push_stroke_point(x, y);
  749.             if (g_pen_stroke_table[MMI_PEN_STROKE_DOWN])
  750.             {
  751.                 (g_pen_stroke_table[MMI_PEN_STROKE_DOWN]) (g_pen_cntx.pen_down_pos);
  752.             }
  753.             if (g_pen_stroke_pre_move)
  754.             {
  755.                 g_pen_stroke_pre_move();
  756.             }
  757.             if (g_pen_stroke_table[MMI_PEN_STROKE_MOVE])
  758.             {
  759.                 (g_pen_stroke_table[MMI_PEN_STROKE_MOVE]) (pos);
  760.             }
  761.             if (g_pen_stroke_post_move)
  762.             {
  763.                 g_pen_stroke_post_move();
  764.             }
  765.         }
  766.         /* Otherwise, ignore the move event */
  767.     }
  768.     else if (g_pen_cntx.is_stroke_event)
  769.     {
  770.         if (g_pen_stroke_pre_move)
  771.         {
  772.             g_pen_stroke_pre_move();
  773.         }
  774.         if (g_pen_stroke_table[MMI_PEN_STROKE_MOVE])
  775.         {
  776.             (g_pen_stroke_table[MMI_PEN_STROKE_MOVE]) (pos);
  777.         }
  778.         if (g_pen_stroke_post_move)
  779.         {
  780.             g_pen_stroke_post_move();
  781.         }
  782.         mmi_pen_simulator_push_stroke_point(x, y);
  783.         if (mmi_pen_simulator_pixel_diff(pos, g_pen_cntx.pen_down_pos) > MMI_PEN_SKIP_STROKE_LONGTAP_OFFSET)
  784.         {
  785.             gui_cancel_timer(mmi_pen_simulator_stroke_longtap_hdlr);
  786.         }
  787.     }
  788.     else
  789.     {
  790.         if (g_pen_event_table[MMI_PEN_EVENT_MOVE])
  791.         {
  792.             (g_pen_event_table[MMI_PEN_EVENT_MOVE]) (pos);
  793.         }
  794.         if (mmi_pen_simulator_pixel_diff(pos, g_pen_cntx.pen_repeat_origin_pos) > MMI_PEN_SKIP_LONGTAP_OFFSET)
  795.         {
  796.             g_pen_cntx.is_waiting_long_tap_event = 0;   /* Wait Pen Repeat because Pen LongTap only happens at the pen down position */
  797.             g_pen_cntx.pen_repeat_origin_pos = pos;
  798.             gui_cancel_timer(mmi_pen_simulator_repeat_hdlr);
  799.             if (g_pen_cntx.is_enabled && g_pen_cntx.is_pen_down)
  800.             {
  801.                 gui_start_timer(MMI_PEN_REPEAT_TIME * 10, mmi_pen_simulator_repeat_hdlr);
  802.             }
  803.         }
  804.     }
  805. }
  806. /*****************************************************************************
  807.  * FUNCTION
  808.  *  mmi_pen_simulator_button_up_hdlr
  809.  * DESCRIPTION
  810.  *  
  811.  * PARAMETERS
  812.  *  x       [IN]        
  813.  *  y       [IN]        
  814.  * RETURNS
  815.  *  void
  816.  *****************************************************************************/
  817. void mmi_pen_simulator_button_up_hdlr(S16 x, S16 y)
  818. {
  819.     /*----------------------------------------------------------------*/
  820.     /* Local Variables                                                */
  821.     /*----------------------------------------------------------------*/
  822.     mmi_pen_point_struct pos;
  823.     /*----------------------------------------------------------------*/
  824.     /* Code Body                                                      */
  825.     /*----------------------------------------------------------------*/
  826.     if (!g_pen_cntx.is_enabled || !g_pen_cntx.is_pen_down)
  827.     {
  828.         return;
  829.     }
  830.     mmi_pen_simulator_fix_point_bound(&x, &y, g_pen_cntx.is_stroke_event && (g_pen_num_stroke_area > 1));
  831.     pos.x = x;
  832.     pos.y = y;
  833.     g_pen_cntx.pen_current_pos = pos;
  834.     g_pen_cntx.is_pen_down = 0;
  835.     if (g_pen_cntx.is_pending_stroke_event)
  836.     {
  837.         if (g_pen_event_table[MMI_PEN_EVENT_UP])
  838.         {
  839.             (g_pen_event_table[MMI_PEN_EVENT_UP]) (g_pen_cntx.pen_down_pos);
  840.         }
  841.     }
  842.     else if (g_pen_cntx.is_stroke_event)
  843.     {
  844.         if (g_pen_stroke_table[MMI_PEN_STROKE_UP])
  845.         {
  846.             (g_pen_stroke_table[MMI_PEN_STROKE_UP]) (pos);
  847.         }
  848.         mmi_pen_simulator_push_stroke_point(x, y);
  849.         mmi_pen_simulator_push_stroke_end();
  850.         gui_cancel_timer(mmi_pen_simulator_stroke_longtap_hdlr);
  851.         if (g_pen_cntx.is_stroke_longtap_event_generated)
  852.         {
  853.             /* Clear strokes */
  854.             mmi_pen_end_strokes_of_character();
  855.             mmi_pen_begin_strokes_of_character();
  856.         }
  857.     }
  858.     else
  859.     {
  860.         gui_cancel_timer(mmi_pen_simulator_repeat_hdlr);
  861.         if (g_pen_event_table[MMI_PEN_EVENT_UP])
  862.         {
  863.             (g_pen_event_table[MMI_PEN_EVENT_UP]) (pos);
  864.         }
  865.     }
  866.     if (g_pen_cntx.reset_stroke_on_pen_up)
  867.     {
  868.         if (g_pen_stroke_max_points > 0)
  869.         {
  870.             mmi_pen_end_strokes_of_character();
  871.             mmi_pen_reset();
  872.             mmi_pen_begin_strokes_of_character();
  873.         }
  874.         else
  875.         {
  876.             mmi_pen_reset();
  877.         }
  878.     }
  879. }
  880. /***************************************************************************** 
  881. * Global Variable
  882. *****************************************************************************/
  883. /***************************************************************************** 
  884. * Global Function
  885. *****************************************************************************/
  886. /* Dummy pen handler */
  887. /*****************************************************************************
  888.  * FUNCTION
  889.  *  mmi_pen_dummy_hdlr
  890.  * DESCRIPTION
  891.  *  
  892.  * PARAMETERS
  893.  *  pos     [IN]        
  894.  * RETURNS
  895.  *  void
  896.  *****************************************************************************/
  897. void mmi_pen_dummy_hdlr(mmi_pen_point_struct pos)
  898. {
  899.     /*----------------------------------------------------------------*/
  900.     /* Local Variables                                                */
  901.     /*----------------------------------------------------------------*/
  902.     /*----------------------------------------------------------------*/
  903.     /* Code Body                                                      */
  904.     /*----------------------------------------------------------------*/
  905.     UI_UNUSED_PARAMETER(pos);
  906. }
  907. /*****************************************************************************
  908.  * FUNCTION
  909.  *  mmi_pen_config_sampling_period
  910.  * DESCRIPTION
  911.  *  
  912.  * PARAMETERS
  913.  *  low         [IN]        
  914.  *  high        [IN]        
  915.  * RETURNS
  916.  *  void
  917.  *****************************************************************************/
  918. void mmi_pen_config_sampling_period(kal_uint32 low, kal_uint32 high)
  919. {
  920.     /*----------------------------------------------------------------*/
  921.     /* Local Variables                                                */
  922.     /*----------------------------------------------------------------*/
  923.     /*----------------------------------------------------------------*/
  924.     /* Code Body                                                      */
  925.     /*----------------------------------------------------------------*/
  926.     /* DUMMY */
  927. }
  928. /*****************************************************************************
  929.  * FUNCTION
  930.  *  mmi_pen_config_timeout_period
  931.  * DESCRIPTION
  932.  *  
  933.  * PARAMETERS
  934.  *  longtap             [IN]        
  935.  *  repeat              [IN]        
  936.  *  stroke_longtap      [IN]        
  937.  * RETURNS
  938.  *  void
  939.  *****************************************************************************/
  940. void mmi_pen_config_timeout_period(kal_uint32 longtap, kal_uint32 repeat, kal_uint32 stroke_longtap)
  941. {
  942.     /*----------------------------------------------------------------*/
  943.     /* Local Variables                                                */
  944.     /*----------------------------------------------------------------*/
  945.     /*----------------------------------------------------------------*/
  946.     /* Code Body                                                      */
  947.     /*----------------------------------------------------------------*/
  948.     /* DUMMY */
  949. }
  950. /*****************************************************************************
  951.  * FUNCTION
  952.  *  mmi_pen_config_move_offset
  953.  * DESCRIPTION
  954.  *  
  955.  * PARAMETERS
  956.  *  event_based         [IN]        
  957.  *  stroke_based        [IN]        
  958.  *  long_tap            [IN]        
  959.  *  stroke_long_tap     [IN]        
  960.  * RETURNS
  961.  *  void
  962.  *****************************************************************************/
  963. void mmi_pen_config_move_offset(
  964.         kal_uint32 event_based,
  965.         kal_uint32 stroke_based,
  966.         kal_uint32 long_tap,
  967.         kal_uint32 stroke_long_tap)
  968. {
  969.     /*----------------------------------------------------------------*/
  970.     /* Local Variables                                                */
  971.     /*----------------------------------------------------------------*/
  972.     /*----------------------------------------------------------------*/
  973.     /* Code Body                                                      */
  974.     /*----------------------------------------------------------------*/
  975.     /* DUMMY */
  976. }
  977. /*****************************************************************************
  978.  * FUNCTION
  979.  *  mmi_pen_init
  980.  * DESCRIPTION
  981.  *  Initialize pen system
  982.  * PARAMETERS
  983.  *  void
  984.  * RETURNS
  985.  *  void
  986.  *****************************************************************************/
  987. void mmi_pen_init(void)
  988. {
  989.     /*----------------------------------------------------------------*/
  990.     /* Local Variables                                                */
  991.     /*----------------------------------------------------------------*/
  992.     /*----------------------------------------------------------------*/
  993.     /* Code Body                                                      */
  994.     /*----------------------------------------------------------------*/
  995. #ifdef __MMI_HANDWRITING_PAD__
  996.     mmi_frm_setup_default_pen_handler();
  997. #endif 
  998. #if !defined(MMI_ON_WIN32)
  999.     SetProtocolEventHandler(mmi_pen_MODIS_tp_ind, MSG_ID_TP_EVENT_IND);
  1000. #endif
  1001. }
  1002. /*****************************************************************************
  1003.  * FUNCTION
  1004.  *  mmi_pen_block
  1005.  * DESCRIPTION
  1006.  *  Block pen system
  1007.  *  
  1008.  *  Note: typically used for keypad lock in idle screen
  1009.  * PARAMETERS
  1010.  *  void
  1011.  * RETURNS
  1012.  *  void
  1013.  *****************************************************************************/
  1014. void mmi_pen_block(void)
  1015. {
  1016.     /*----------------------------------------------------------------*/
  1017.     /* Local Variables                                                */
  1018.     /*----------------------------------------------------------------*/
  1019.     /*----------------------------------------------------------------*/
  1020.     /* Code Body                                                      */
  1021.     /*----------------------------------------------------------------*/
  1022.     mmi_pen_disable();
  1023.     g_pen_cntx.is_blocked = 1;
  1024. }
  1025. /*****************************************************************************
  1026.  * FUNCTION
  1027.  *  mmi_pen_unblock
  1028.  * DESCRIPTION
  1029.  *  Unblock pen system
  1030.  *  
  1031.  *  Note: typically used for keypad lock in idle screen
  1032.  * PARAMETERS
  1033.  *  void
  1034.  * RETURNS
  1035.  *  void
  1036.  *****************************************************************************/
  1037. void mmi_pen_unblock(void)
  1038. {
  1039.     /*----------------------------------------------------------------*/
  1040.     /* Local Variables                                                */
  1041.     /*----------------------------------------------------------------*/
  1042.     /*----------------------------------------------------------------*/
  1043.     /* Code Body                                                      */
  1044.     /*----------------------------------------------------------------*/
  1045.     g_pen_cntx.is_blocked = 0;
  1046.     mmi_pen_enable();
  1047. }
  1048. /*****************************************************************************
  1049.  * FUNCTION
  1050.  *  mmi_pen_enable
  1051.  * DESCRIPTION
  1052.  *  Enable pen system
  1053.  *  
  1054.  *  Note: typically on Keypad Up
  1055.  * PARAMETERS
  1056.  *  void
  1057.  * RETURNS
  1058.  *  void
  1059.  *****************************************************************************/
  1060. void mmi_pen_enable(void)
  1061. {
  1062.     /*----------------------------------------------------------------*/
  1063.     /* Local Variables                                                */
  1064.     /*----------------------------------------------------------------*/
  1065.     /*----------------------------------------------------------------*/
  1066.     /* Code Body                                                      */
  1067.     /*----------------------------------------------------------------*/
  1068.     if (g_pen_cntx.is_blocked || g_pen_cntx.is_enabled)
  1069.     {
  1070.         return;
  1071.     }
  1072.     memset(&g_pen_cntx, 0, sizeof(g_pen_cntx));
  1073.     g_pen_cntx.is_enabled = 1;
  1074. #if !defined(MMI_ON_WIN32)
  1075.     mmi_pen_MODIS_start_timer();
  1076. #endif 
  1077. }
  1078. /*****************************************************************************
  1079.  * FUNCTION
  1080.  *  mmi_pen_disable
  1081.  * DESCRIPTION
  1082.  *  Disable pen system
  1083.  *  
  1084.  *  Note: typically on Keypad Down because we don't want to use keypad and touch screen
  1085.  *  at the same time
  1086.  * PARAMETERS
  1087.  *  void
  1088.  * RETURNS
  1089.  *  void
  1090.  *****************************************************************************/
  1091. void mmi_pen_disable(void)
  1092. {
  1093.     /*----------------------------------------------------------------*/
  1094.     /* Local Variables                                                */
  1095.     /*----------------------------------------------------------------*/
  1096.     /*----------------------------------------------------------------*/
  1097.     /* Code Body                                                      */
  1098.     /*----------------------------------------------------------------*/
  1099.     if (g_pen_cntx.is_blocked || !g_pen_cntx.is_enabled)
  1100.     {
  1101.         return;
  1102.     }
  1103.     gui_cancel_timer(mmi_pen_simulator_repeat_hdlr);
  1104.     if (g_pen_cntx.is_pen_down)
  1105.     {
  1106.         if (g_pen_event_table[MMI_PEN_EVENT_ABORT])
  1107.         {
  1108.             (g_pen_event_table[MMI_PEN_EVENT_ABORT]) (g_pen_cntx.pen_current_pos);
  1109.         }
  1110.     }
  1111.     memset(&g_pen_cntx, 0, sizeof(g_pen_cntx));
  1112. #if !defined(MMI_ON_WIN32)
  1113.     mmi_pen_MODIS_flush_queue();
  1114. #endif 
  1115. }
  1116. /*****************************************************************************
  1117.  * FUNCTION
  1118.  *  mmi_pen_reset
  1119.  * DESCRIPTION
  1120.  *  Reset the status of touch screen
  1121.  *  - Flush event queue
  1122.  *  - If the pen is currently tapped down, ignore all subsequent pen events until the pen is up.
  1123.  *  
  1124.  *  Note: typically on MMI screen switching
  1125.  * PARAMETERS
  1126.  *  void
  1127.  * RETURNS
  1128.  *  void
  1129.  *****************************************************************************/
  1130. void mmi_pen_reset(void)
  1131. {
  1132.     /*----------------------------------------------------------------*/
  1133.     /* Local Variables                                                */
  1134.     /*----------------------------------------------------------------*/
  1135.     /*----------------------------------------------------------------*/
  1136.     /* Code Body                                                      */
  1137.     /*----------------------------------------------------------------*/
  1138.     if (g_pen_cntx.is_blocked || !g_pen_cntx.is_enabled)
  1139.     {
  1140.         return;
  1141.     }
  1142.     gui_cancel_timer(mmi_pen_simulator_repeat_hdlr);
  1143.     if (g_pen_cntx.is_pen_down)
  1144.     {
  1145.         gui_cancel_timer(mmi_pen_simulator_repeat_hdlr);
  1146.         if (g_pen_event_table[MMI_PEN_EVENT_ABORT])
  1147.         {
  1148.             (g_pen_event_table[MMI_PEN_EVENT_ABORT]) (g_pen_cntx.pen_current_pos);
  1149.         }
  1150.     }
  1151.     memset(&g_pen_cntx, 0, sizeof(g_pen_cntx));
  1152.     g_pen_cntx.is_enabled = 1;
  1153. #if !defined(MMI_ON_WIN32)
  1154.     mmi_pen_MODIS_flush_queue();
  1155. #endif 
  1156. }
  1157. /*****************************************************************************
  1158.  * FUNCTION
  1159.  *  mmi_pen_get_state
  1160.  * DESCRIPTION
  1161.  *  Get the current state of touch screen
  1162.  * PARAMETERS
  1163.  *  is_enabled      [OUT]         
  1164.  *  is_pen_down     [OUT]         
  1165.  * RETURNS
  1166.  *  void
  1167.  *****************************************************************************/
  1168. void mmi_pen_get_state(kal_bool *is_enabled, kal_bool *is_pen_down)
  1169. {
  1170.     /*----------------------------------------------------------------*/
  1171.     /* Local Variables                                                */
  1172.     /*----------------------------------------------------------------*/
  1173.     /*----------------------------------------------------------------*/
  1174.     /* Code Body                                                      */
  1175.     /*----------------------------------------------------------------*/
  1176.     if (g_pen_cntx.is_enabled)
  1177.     {
  1178.         *is_enabled = KAL_TRUE;
  1179.         if (g_pen_cntx.is_pen_down)
  1180.         {
  1181.             *is_pen_down = KAL_TRUE;
  1182.         }
  1183.         else
  1184.         {
  1185.             *is_pen_down = KAL_FALSE;
  1186.         }
  1187.     }
  1188.     else
  1189.     {
  1190.         *is_enabled = KAL_FALSE;
  1191.         *is_pen_down = KAL_FALSE;
  1192.     }
  1193. }
  1194. /*****************************************************************************
  1195.  * FUNCTION
  1196.  *  mmi_pen_start_calibration
  1197.  * DESCRIPTION
  1198.  *  Start pen calibration
  1199.  * PARAMETERS
  1200.  *  num         [IN]        Number of calibration points
  1201.  *  points      [IN]        Calibration points
  1202.  * RETURNS
  1203.  *  void
  1204.  * REMARKS
  1205.  *  After mmi_pen_reset(), the calibration process is terminated.
  1206.  *****************************************************************************/
  1207. void mmi_pen_start_calibration(kal_uint16 num, const mmi_pen_point_struct *points)
  1208. {
  1209.     /*----------------------------------------------------------------*/
  1210.     /* Local Variables                                                */
  1211.     /*----------------------------------------------------------------*/
  1212.     /*----------------------------------------------------------------*/
  1213.     /* Code Body                                                      */
  1214.     /*----------------------------------------------------------------*/
  1215.     /* DUMMY */
  1216. }
  1217. /*****************************************************************************
  1218.  * FUNCTION
  1219.  *  mmi_pen_set_calibration_data
  1220.  * DESCRIPTION
  1221.  *  Assign driver calibration data
  1222.  * PARAMETERS
  1223.  *  data        [IN]        
  1224.  * RETURNS
  1225.  *  void
  1226.  * REMARKS
  1227.  *  
  1228.  *****************************************************************************/
  1229. void mmi_pen_set_calibration_data(const mmi_pen_calibration_struct *data)
  1230. {
  1231.     /*----------------------------------------------------------------*/
  1232.     /* Local Variables                                                */
  1233.     /*----------------------------------------------------------------*/
  1234.     /*----------------------------------------------------------------*/
  1235.     /* Code Body                                                      */
  1236.     /*----------------------------------------------------------------*/
  1237.     /* DUMMY */
  1238. }
  1239. /*****************************************************************************
  1240.  * FUNCTION
  1241.  *  mmi_pen_read_calibration_data
  1242.  * DESCRIPTION
  1243.  *  Read the current value of driver calibration data
  1244.  * PARAMETERS
  1245.  *  data        [OUT]       
  1246.  * RETURNS
  1247.  *  void
  1248.  * REMARKS
  1249.  *  
  1250.  *****************************************************************************/
  1251. void mmi_pen_read_calibration_data(mmi_pen_calibration_struct *data)
  1252. {
  1253.     /*----------------------------------------------------------------*/
  1254.     /* Local Variables                                                */
  1255.     /*----------------------------------------------------------------*/
  1256.     /*----------------------------------------------------------------*/
  1257.     /* Code Body                                                      */
  1258.     /*----------------------------------------------------------------*/
  1259.     /* DUMMY */
  1260. }
  1261. /*****************************************************************************
  1262.  * FUNCTION
  1263.  *  mmi_pen_register_down_handler
  1264.  * DESCRIPTION
  1265.  *  Register the Pen Down handler
  1266.  * PARAMETERS
  1267.  *  pen_fp      [IN]        Callback handler
  1268.  * RETURNS
  1269.  *  void
  1270.  *****************************************************************************/
  1271. void mmi_pen_register_down_handler(mmi_pen_hdlr pen_fp)
  1272. {
  1273.     /*----------------------------------------------------------------*/
  1274.     /* Local Variables                                                */
  1275.     /*----------------------------------------------------------------*/
  1276.     /*----------------------------------------------------------------*/
  1277.     /* Code Body                                                      */
  1278.     /*----------------------------------------------------------------*/
  1279.     g_pen_event_table[MMI_PEN_EVENT_DOWN] = pen_fp;
  1280. }
  1281. /*****************************************************************************
  1282.  * FUNCTION
  1283.  *  mmi_pen_register_long_tap_handler
  1284.  * DESCRIPTION
  1285.  *  Register the Pen LongTap handler
  1286.  *  
  1287.  *  LongTap handler is invoked when  the pen is tapped for a period of time
  1288.  *  and stays at the same place where it is tapped down.
  1289.  *  
  1290.  *  It is invoked atmost one time before pen up.
  1291.  * PARAMETERS
  1292.  *  pen_fp      [IN]        Callback handler
  1293.  * RETURNS
  1294.  *  void
  1295.  *****************************************************************************/
  1296. void mmi_pen_register_long_tap_handler(mmi_pen_hdlr pen_fp)
  1297. {
  1298.     /*----------------------------------------------------------------*/
  1299.     /* Local Variables                                                */
  1300.     /*----------------------------------------------------------------*/
  1301.     /*----------------------------------------------------------------*/
  1302.     /* Code Body                                                      */
  1303.     /*----------------------------------------------------------------*/
  1304.     g_pen_event_table[MMI_PEN_EVENT_LONG_TAP] = pen_fp;
  1305. }
  1306. /*****************************************************************************
  1307.  * FUNCTION
  1308.  *  mmi_pen_register_repeat_handler
  1309.  * DESCRIPTION
  1310.  *  Register the Pen Repeat handler.
  1311.  *  
  1312.  *  Repeat handler is invoked after LongTap handler.
  1313.  *  However, unlike LongTap handler, Repeat handler is invoked even if
  1314.  *  it does not stays at the same place as Pen Down.
  1315.  *  
  1316.  *  it might be invoked more than one times before pen up.
  1317.  * PARAMETERS
  1318.  *  pen_fp      [IN]        Callback handler
  1319.  * RETURNS
  1320.  *  void
  1321.  *****************************************************************************/
  1322. void mmi_pen_register_repeat_handler(mmi_pen_hdlr pen_fp)
  1323. {
  1324.     /*----------------------------------------------------------------*/
  1325.     /* Local Variables                                                */
  1326.     /*----------------------------------------------------------------*/
  1327.     /*----------------------------------------------------------------*/
  1328.     /* Code Body                                                      */
  1329.     /*----------------------------------------------------------------*/
  1330.     g_pen_event_table[MMI_PEN_EVENT_REPEAT] = pen_fp;
  1331. }
  1332. /*****************************************************************************
  1333.  * FUNCTION
  1334.  *  mmi_pen_register_move_handler
  1335.  * DESCRIPTION
  1336.  *  Register the Pen Move handler.
  1337.  *  
  1338.  *  The invocation frequency of Pen Move handler is typically less than driver sampling rate.
  1339.  * PARAMETERS
  1340.  *  pen_fp      [IN]        Callback handler
  1341.  * RETURNS
  1342.  *  void
  1343.  *****************************************************************************/
  1344. void mmi_pen_register_move_handler(mmi_pen_hdlr pen_fp)
  1345. {
  1346.     /*----------------------------------------------------------------*/
  1347.     /* Local Variables                                                */
  1348.     /*----------------------------------------------------------------*/
  1349.     /*----------------------------------------------------------------*/
  1350.     /* Code Body                                                      */
  1351.     /*----------------------------------------------------------------*/
  1352.     g_pen_event_table[MMI_PEN_EVENT_MOVE] = pen_fp;
  1353. }
  1354. /*****************************************************************************
  1355.  * FUNCTION
  1356.  *  mmi_pen_register_up_handler
  1357.  * DESCRIPTION
  1358.  *  Register the Pen Up handler.
  1359.  * PARAMETERS
  1360.  *  pen_fp      [IN]        
  1361.  * RETURNS
  1362.  *  void
  1363.  *****************************************************************************/
  1364. void mmi_pen_register_up_handler(mmi_pen_hdlr pen_fp)
  1365. {
  1366.     /*----------------------------------------------------------------*/
  1367.     /* Local Variables                                                */
  1368.     /*----------------------------------------------------------------*/
  1369.     /*----------------------------------------------------------------*/
  1370.     /* Code Body                                                      */
  1371.     /*----------------------------------------------------------------*/
  1372.     g_pen_event_table[MMI_PEN_EVENT_UP] = pen_fp;
  1373. }
  1374. /*****************************************************************************
  1375.  * FUNCTION
  1376.  *  mmi_pen_register_abort_handler
  1377.  * DESCRIPTION
  1378.  *  Register the Pen Abort handler.
  1379.  * PARAMETERS
  1380.  *  pen_fp      [IN]        
  1381.  * RETURNS
  1382.  *  void
  1383.  *****************************************************************************/
  1384. void mmi_pen_register_abort_handler(mmi_pen_hdlr pen_fp)
  1385. {
  1386.     /*----------------------------------------------------------------*/
  1387.     /* Local Variables                                                */
  1388.     /*----------------------------------------------------------------*/
  1389.     /*----------------------------------------------------------------*/
  1390.     /* Code Body                                                      */
  1391.     /*----------------------------------------------------------------*/
  1392.     g_pen_event_table[MMI_PEN_EVENT_ABORT] = pen_fp;
  1393. }
  1394. /*****************************************************************************
  1395.  * FUNCTION
  1396.  *  mmi_pen_start_capture_strokes
  1397.  * DESCRIPTION
  1398.  *  Win32 port of mmi_pen_start_capture_strokes
  1399.  * PARAMETERS
  1400.  *  max_points          [IN]        Maximum number of points can be en-queued.
  1401.  *  point_array         [IN]        Array for storing sampled points in strokes.
  1402.  *  num_regions         [IN]        Number of handwriting regions
  1403.  *  region_array        [IN]        Handwriting regions
  1404.  *  ext_region          [IN]        Handwriting region after the first stroke is generated. (NULL to ignore it)
  1405.  * RETURNS
  1406.  *  void
  1407.  *****************************************************************************/
  1408. void mmi_pen_start_capture_strokes(
  1409.         kal_uint32 max_points,
  1410.         mmi_pen_point_struct *point_array,
  1411.         kal_uint32 num_regions,
  1412.         const mmi_pen_handwriting_area_struct *region_array,
  1413.         const mmi_pen_handwriting_area_struct *ext_region)
  1414. {
  1415.     /*----------------------------------------------------------------*/
  1416.     /* Local Variables                                                */
  1417.     /*----------------------------------------------------------------*/
  1418.     /*----------------------------------------------------------------*/
  1419.     /* Code Body                                                      */
  1420.     /*----------------------------------------------------------------*/
  1421.     /* Multi-block mode does not have extended region. Otherwise, it cannot switch to another 
  1422.        block and multi-block feature is broken. */
  1423.     MMI_ASSERT(ext_region == NULL || num_regions == 1);
  1424.     
  1425.     if (num_regions > MMI_PEN_MAX_HANDWRITING_REGION)
  1426.     {
  1427.         num_regions = MMI_PEN_MAX_HANDWRITING_REGION;
  1428.     }
  1429.     
  1430.     g_pen_num_stroke_area = num_regions;
  1431.     memcpy(g_pen_stroke_areas, region_array, sizeof(mmi_pen_handwriting_area_struct) * num_regions);
  1432.     if (ext_region)
  1433.     {
  1434.         g_pen_ext_stroke_area = *ext_region;
  1435.     }
  1436.     else
  1437.     {
  1438.         g_pen_ext_stroke_area.x1 = -1;
  1439.         g_pen_ext_stroke_area.x2 = -1;
  1440.         g_pen_ext_stroke_area.y1 = -1;
  1441.         g_pen_ext_stroke_area.y2 = -1;
  1442.     }
  1443.     if (num_regions == 1)
  1444.     {
  1445.         g_pen_stroke_min_offset = MMI_PEN_STROKE_MIN_OFFSET;
  1446.     }
  1447.     else
  1448.     {
  1449.         g_pen_stroke_min_offset = 0;
  1450.     }
  1451.     g_pen_stroke_max_points = max_points;
  1452.     g_pen_stroke_points = point_array;
  1453. }
  1454. /*****************************************************************************
  1455.  * FUNCTION
  1456.  *  mmi_pen_change_handwriting_area
  1457.  * DESCRIPTION
  1458.  *  Win32 port of mmi_pen_change_handwriting_area
  1459.  * PARAMETERS
  1460.  *  num_regions         [IN]        Number of handwriting regions
  1461.  *  region_array        [IN]        Handwriting regions
  1462.  *  ext_region          [IN]        Handwriting region after the first stroke is generated. (NULL to ignore it)
  1463.  * RETURNS
  1464.  *  void
  1465.  *****************************************************************************/
  1466. void mmi_pen_change_handwriting_area(
  1467.         kal_uint32 num_regions,
  1468.         const mmi_pen_handwriting_area_struct *region_array,
  1469.         const mmi_pen_handwriting_area_struct *ext_region)
  1470. {
  1471.     /*----------------------------------------------------------------*/
  1472.     /* Local Variables                                                */
  1473.     /*----------------------------------------------------------------*/
  1474.     /*----------------------------------------------------------------*/
  1475.     /* Code Body                                                      */
  1476.     /*----------------------------------------------------------------*/
  1477.     if (g_pen_stroke_max_points == 0) /* Handwriting is not enabled */
  1478.     {
  1479.         /* MMI_DBG_ASSERT(0); */
  1480.         return;
  1481.     }
  1482.     /* Multi-block mode does not have extended region */
  1483.     MMI_ASSERT(ext_region == NULL || num_regions == 1);
  1484.     
  1485.     if (num_regions > MMI_PEN_MAX_HANDWRITING_REGION)
  1486.     {
  1487.         num_regions = MMI_PEN_MAX_HANDWRITING_REGION;
  1488.     }
  1489.     g_pen_num_stroke_area = num_regions;
  1490.     memcpy(g_pen_stroke_areas, region_array, sizeof(mmi_pen_handwriting_area_struct) * num_regions);
  1491.     if (ext_region)
  1492.     {
  1493.         g_pen_ext_stroke_area = *ext_region;
  1494.     }
  1495.     else
  1496.     {
  1497.         g_pen_ext_stroke_area.x1 = -1;
  1498.         g_pen_ext_stroke_area.x2 = -1;
  1499.         g_pen_ext_stroke_area.y1 = -1;
  1500.         g_pen_ext_stroke_area.y2 = -1;
  1501.     }
  1502.     if (num_regions == 1)
  1503.     {
  1504.         g_pen_stroke_min_offset = MMI_PEN_STROKE_MIN_OFFSET;
  1505.     }
  1506.     else
  1507.     {
  1508.         g_pen_stroke_min_offset = 0;
  1509.     }
  1510.     /* 
  1511.      * We will call mmi_pen_reset() *later* on Pen Up or Stroke Up event.
  1512.      *
  1513.      * There might be many pending events in driver queue if MMI task is blocked by 
  1514.      * other time-consuming jobs. If there are pending stroke events in driver queue, 
  1515.      * it is better to flush driver queue.
  1516.      *
  1517.      */
  1518.     if (!g_pen_cntx.is_pen_down)
  1519.     {
  1520.         /* Clear strokes */
  1521.         mmi_pen_end_strokes_of_character();
  1522.         mmi_pen_reset();
  1523.         mmi_pen_begin_strokes_of_character();
  1524.     }
  1525.     else
  1526.     {
  1527.         /* 
  1528.          * NOTE: we *cannot* call mmi_pen_reset().
  1529.          *
  1530.          * For example, assume mmi_pen_change_handwriting_area() is invoked on Button Down.
  1531.          * If we invoke mmi_pen_reset() here, it will send MMI_PEN_EVENT_ABORT and reset the button.
  1532.          */
  1533.         g_pen_cntx.reset_stroke_on_pen_up = 1;
  1534.     }
  1535. }
  1536. /*****************************************************************************
  1537.  * FUNCTION
  1538.  *  mmi_pen_stop_capture_strokes
  1539.  * DESCRIPTION
  1540.  *  Stop capturing stroke
  1541.  *  
  1542.  *  Note: it should be used before mmi_pen_reset() because it does not flush driver pen queue
  1543.  * PARAMETERS
  1544.  *  void
  1545.  * RETURNS
  1546.  *  void
  1547.  *****************************************************************************/
  1548. void mmi_pen_stop_capture_strokes(void)
  1549. {
  1550.     /*----------------------------------------------------------------*/
  1551.     /* Local Variables                                                */
  1552.     /*----------------------------------------------------------------*/
  1553.     /*----------------------------------------------------------------*/
  1554.     /* Code Body                                                      */
  1555.     /*----------------------------------------------------------------*/
  1556.     g_pen_num_stroke_area = 0;
  1557.     g_pen_stroke_max_points = 0;
  1558.     g_pen_stroke_points = NULL;
  1559.     /* 
  1560.      * We will call mmi_pen_reset() *later* on Pen Up or Stroke Up event.
  1561.      *
  1562.      * There might be many pending events in driver queue if MMI task is blocked by 
  1563.      * other time-consuming jobs. If there are pending stroke events in driver queue, 
  1564.      * it is better to flush driver queue.
  1565.      *
  1566.      */
  1567.     if (!g_pen_cntx.is_pen_down)
  1568.     {
  1569.         mmi_pen_reset();
  1570.     }
  1571.     else
  1572.     {
  1573.         /* 
  1574.          * NOTE: we *cannot* call mmi_pen_reset().
  1575.          *
  1576.          * For example, assume mmi_pen_stop_capture_strokes() is invoked when scrollbar of inline editor 
  1577.          * is scrolled on Pen Move event and the highlighed single-line editor is un-highlighted. 
  1578.          * If we invoke mmi_pen_reset() here, it will send MMI_PEN_EVENT_ABORT and reset the scrolling of scrollbar.
  1579.          */
  1580.         g_pen_cntx.reset_stroke_on_pen_up = 1;
  1581.     }
  1582. }
  1583. /*****************************************************************************
  1584.  * FUNCTION
  1585.  *  mmi_pen_register_stroke_down_handler
  1586.  * DESCRIPTION
  1587.  *  Register the Stroke Down handler
  1588.  * PARAMETERS
  1589.  *  pen_fp      [IN]        Callback handler
  1590.  * RETURNS
  1591.  *  void
  1592.  *****************************************************************************/
  1593. void mmi_pen_register_stroke_down_handler(mmi_pen_hdlr pen_fp)
  1594. {
  1595.     /*----------------------------------------------------------------*/
  1596.     /* Local Variables                                                */
  1597.     /*----------------------------------------------------------------*/
  1598.     /*----------------------------------------------------------------*/
  1599.     /* Code Body                                                      */
  1600.     /*----------------------------------------------------------------*/
  1601.     g_pen_stroke_table[MMI_PEN_STROKE_DOWN] = pen_fp;
  1602. }
  1603. /*****************************************************************************
  1604.  * FUNCTION
  1605.  *  mmi_pen_register_stroke_move_handler
  1606.  * DESCRIPTION
  1607.  *  Register the Stroke Move handler
  1608.  * PARAMETERS
  1609.  *  begin_fp        [IN]        
  1610.  *  end_fp          [IN]        
  1611.  *  pen_fp          [IN]        Callback handler
  1612.  * RETURNS
  1613.  *  void
  1614.  *****************************************************************************/
  1615. void mmi_pen_register_stroke_move_handler(void (*begin_fp) (void), void (*end_fp) (void), mmi_pen_hdlr pen_fp)
  1616. {
  1617.     /*----------------------------------------------------------------*/
  1618.     /* Local Variables                                                */
  1619.     /*----------------------------------------------------------------*/
  1620.     /*----------------------------------------------------------------*/
  1621.     /* Code Body                                                      */
  1622.     /*----------------------------------------------------------------*/
  1623.     g_pen_stroke_pre_move = begin_fp;
  1624.     g_pen_stroke_table[MMI_PEN_STROKE_MOVE] = pen_fp;
  1625.     g_pen_stroke_post_move = end_fp;
  1626. }
  1627. /*****************************************************************************
  1628.  * FUNCTION
  1629.  *  mmi_pen_register_stroke_up_handler
  1630.  * DESCRIPTION
  1631.  *  Register the Stroke Up handler
  1632.  * PARAMETERS
  1633.  *  pen_fp      [IN]        Callback handler
  1634.  * RETURNS
  1635.  *  void
  1636.  *****************************************************************************/
  1637. void mmi_pen_register_stroke_up_handler(mmi_pen_hdlr pen_fp)
  1638. {
  1639.     /*----------------------------------------------------------------*/
  1640.     /* Local Variables                                                */
  1641.     /*----------------------------------------------------------------*/
  1642.     /*----------------------------------------------------------------*/
  1643.     /* Code Body                                                      */
  1644.     /*----------------------------------------------------------------*/
  1645.     g_pen_stroke_table[MMI_PEN_STROKE_UP] = pen_fp;
  1646. }
  1647. /*****************************************************************************
  1648.  * FUNCTION
  1649.  *  mmi_pen_register_stroke_longtap_handler
  1650.  * DESCRIPTION
  1651.  *  Register the Stroke Up handler
  1652.  * PARAMETERS
  1653.  *  pen_fp      [IN]        Callback handler
  1654.  * RETURNS
  1655.  *  void
  1656.  *****************************************************************************/
  1657. void mmi_pen_register_stroke_longtap_handler(mmi_pen_hdlr pen_fp)
  1658. {
  1659.     /*----------------------------------------------------------------*/
  1660.     /* Local Variables                                                */
  1661.     /*----------------------------------------------------------------*/
  1662.     /*----------------------------------------------------------------*/
  1663.     /* Code Body                                                      */
  1664.     /*----------------------------------------------------------------*/
  1665.     g_pen_stroke_table[MMI_PEN_STROKE_LONGTAP] = pen_fp;
  1666. }
  1667. /*****************************************************************************
  1668.  * FUNCTION
  1669.  *  mmi_pen_peek_stroke_state
  1670.  * DESCRIPTION
  1671.  *  
  1672.  * PARAMETERS
  1673.  *  has_unfinished_stroke       [OUT]       Whether there are more strokes to come
  1674.  * RETURNS
  1675.  *  void
  1676.  *****************************************************************************/
  1677. void mmi_pen_peek_stroke_state(BOOL *has_unfinished_stroke)
  1678. {
  1679.     /*----------------------------------------------------------------*/
  1680.     /* Local Variables                                                */
  1681.     /*----------------------------------------------------------------*/
  1682.     /*----------------------------------------------------------------*/
  1683.     /* Code Body                                                      */
  1684.     /*----------------------------------------------------------------*/
  1685.     if (g_pen_cntx.is_pen_down && g_pen_cntx.is_stroke_created)
  1686.     {
  1687.         *has_unfinished_stroke = MMI_TRUE;
  1688.     }
  1689.     else
  1690.     {
  1691.         *has_unfinished_stroke = MMI_FALSE;
  1692.     }
  1693. }
  1694. /*****************************************************************************
  1695.  * FUNCTION
  1696.  *  mmi_pen_begin_strokes_of_character
  1697.  * DESCRIPTION
  1698.  *  Start to write a new character
  1699.  *  
  1700.  *  It is typically coupled with mmi_pen_end_strokes_of_character(), which stops en-queueing
  1701.  *  strokes inside 'point_array'.
  1702.  *  In mmi_pen_begin_strokes_of_character(), MMI continue to en-queue strokes from the head of 'point_array'.
  1703.  *  
  1704.  *  (However, simulator does not implement all of these)
  1705.  * PARAMETERS
  1706.  *  void
  1707.  * RETURNS
  1708.  *  void
  1709.  *****************************************************************************/
  1710. void mmi_pen_begin_strokes_of_character(void)
  1711. {
  1712.     /*----------------------------------------------------------------*/
  1713.     /* Local Variables                                                */
  1714.     /*----------------------------------------------------------------*/
  1715.     /*----------------------------------------------------------------*/
  1716.     /* Code Body                                                      */
  1717.     /*----------------------------------------------------------------*/
  1718.     MMI_DBG_ASSERT(g_pen_num_stroke_area > 0);
  1719.     g_pen_cntx.num_points_queued = 0;
  1720.     g_pen_cntx.is_stroke_created = 0;
  1721.     g_pen_cntx.is_all_stroke_finished = 0;
  1722. }
  1723. /*****************************************************************************
  1724.  * FUNCTION
  1725.  *  mmi_pen_end_strokes_of_character
  1726.  * DESCRIPTION
  1727.  *  End a written character.
  1728.  *  
  1729.  *  The following procedures are executed
  1730.  *  o Reset handwriting area to original size
  1731.  *  o Stop en-queueing new strokes inside 'point_array'. (But incoming strokes are still en-queued in driver ring buffer)
  1732.  *  o Append end marker (0xffff, 0xffff) in 'point_array'
  1733.  *  This API should be used only if there is no unfinished stroke (checked by mmi_pen_peek_stroke_state()).
  1734.  *  After it returns, we may pass 'point_array' to handwriting recognition engine.
  1735.  *  
  1736.  *  (However, simulator does not implement all of these)
  1737.  * PARAMETERS
  1738.  *  void
  1739.  * RETURNS
  1740.  *  void
  1741.  *****************************************************************************/
  1742. void mmi_pen_end_strokes_of_character(void)
  1743. {
  1744.     /*----------------------------------------------------------------*/
  1745.     /* Local Variables                                                */
  1746.     /*----------------------------------------------------------------*/
  1747.     /*----------------------------------------------------------------*/
  1748.     /* Code Body                                                      */
  1749.     /*----------------------------------------------------------------*/ 
  1750.     mmi_pen_simulator_push_char_end();
  1751.     g_pen_cntx.is_all_stroke_finished = 1;  /* To block further Pen Down */
  1752. #ifdef MMI_PEN_SAVE_STROKE_IN_FILE
  1753.     {
  1754.         extern void mmi_pen_save_stroke_in_file(mmi_pen_point_struct *, S32);
  1755.         mmi_pen_save_stroke_in_file(g_pen_stroke_points, g_pen_cntx.num_points_queued);
  1756.     }
  1757. #endif /* MMI_PEN_SAVE_STROKE_IN_FILE */ 
  1758. }
  1759. /****************************************************************
  1760.  * 
  1761.  * MODIS support 
  1762.  *
  1763.  * Because the pen handlers might take a long time to execute, race condition is easy to happen.
  1764.  *
  1765.  ***************************************************************/
  1766. #if !defined(MMI_ON_WIN32)
  1767. #define MMI_PEN_MODIS_QUEUE_SIZE 1024
  1768. typedef struct
  1769. {
  1770.     S16 type;   /* 0 down, 1 move, 2 up */
  1771.     S16 x;
  1772.     S16 y;
  1773. } mmi_pen_MODIS_queue_item_struct;
  1774. static volatile int g_mmi_pen_MODIS_qhead;  /* modified by MMI thread */
  1775. static volatile int g_mmi_pen_MODIS_qtail;  /* modified by windows message loop thread */
  1776. static mmi_pen_MODIS_queue_item_struct g_mmi_pen_MODIS_queue[MMI_PEN_MODIS_QUEUE_SIZE];
  1777. static BOOL g_mmi_pen_MODIS_timer_flag;
  1778. /* By Windows main thread */
  1779. /*****************************************************************************
  1780.  * FUNCTION
  1781.  *  mmi_pen_MODIS_enqueue_point
  1782.  * DESCRIPTION
  1783.  *  
  1784.  * PARAMETERS
  1785.  *  type        [IN]        
  1786.  *  x           [IN]        
  1787.  *  y           [IN]        
  1788.  * RETURNS
  1789.  *  void
  1790.  *****************************************************************************/
  1791. static void mmi_pen_MODIS_enqueue_point(S16 type, S16 x, S16 y)
  1792. {
  1793.     /*----------------------------------------------------------------*/
  1794.     /* Local Variables                                                */
  1795.     /*----------------------------------------------------------------*/
  1796.     int tail = g_mmi_pen_MODIS_qtail;
  1797.     /*----------------------------------------------------------------*/
  1798.     /* Code Body                                                      */
  1799.     /*----------------------------------------------------------------*/
  1800.     g_mmi_pen_MODIS_queue[tail].type = type;
  1801.     g_mmi_pen_MODIS_queue[tail].x = x;
  1802.     g_mmi_pen_MODIS_queue[tail].y = y;
  1803.     if (++tail == MMI_PEN_MODIS_QUEUE_SIZE)
  1804.     {
  1805.         tail = 0;
  1806.     }
  1807.     g_mmi_pen_MODIS_qtail = tail;
  1808.     MMI_ASSERT(tail != g_mmi_pen_MODIS_qhead);
  1809. }
  1810. /*****************************************************************************
  1811.  * FUNCTION
  1812.  *  mmi_pen_MODIS_enqueue_down
  1813.  * DESCRIPTION
  1814.  *  Remark: Executed from non-MMI task
  1815.  * PARAMETERS
  1816.  *  x       [IN]        
  1817.  *  y       [IN]        
  1818.  * RETURNS
  1819.  *  void
  1820.  *****************************************************************************/
  1821. void mmi_pen_MODIS_enqueue_down(S16 x, S16 y)
  1822. {
  1823.     /*----------------------------------------------------------------*/
  1824.     /* Local Variables                                                */
  1825.     /*----------------------------------------------------------------*/
  1826.     MYQUEUE message;
  1827.     /*----------------------------------------------------------------*/
  1828.     /* Code Body                                                      */
  1829.     /*----------------------------------------------------------------*/
  1830.     mmi_pen_MODIS_enqueue_point(0, x, y);
  1831.     
  1832.     /* 
  1833.      * Because polling timer is aligned timer, and it will be suspended if 
  1834.      * the backlight is turned off. We need to send primitive MSG_ID_TP_EVENT_IND
  1835.      * to MMI task in order to resume non-aligned timer.
  1836.      */
  1837.     message.oslMsgId = MSG_ID_TP_EVENT_IND;
  1838.     message.oslDataPtr = NULL;
  1839.     message.oslPeerBuffPtr = NULL;
  1840.     message.oslSrcId = MOD_L4C;
  1841.     message.oslDestId = MOD_MMI;
  1842.     OslMsgSendExtQueue(&message);
  1843. }
  1844. /*****************************************************************************
  1845.  * FUNCTION
  1846.  *  mmi_pen_MODIS_enqueue_move
  1847.  * DESCRIPTION
  1848.  *  
  1849.  * PARAMETERS
  1850.  *  x       [IN]        
  1851.  *  y       [IN]        
  1852.  * RETURNS
  1853.  *  void
  1854.  *****************************************************************************/
  1855. void mmi_pen_MODIS_enqueue_move(S16 x, S16 y)
  1856. {
  1857.     /*----------------------------------------------------------------*/
  1858.     /* Local Variables                                                */
  1859.     /*----------------------------------------------------------------*/
  1860.     /*----------------------------------------------------------------*/
  1861.     /* Code Body                                                      */
  1862.     /*----------------------------------------------------------------*/
  1863.     mmi_pen_MODIS_enqueue_point(1, x, y);
  1864. }
  1865. /*****************************************************************************
  1866.  * FUNCTION
  1867.  *  mmi_pen_MODIS_enqueue_up
  1868.  * DESCRIPTION
  1869.  *  
  1870.  * PARAMETERS
  1871.  *  x       [IN]        
  1872.  *  y       [IN]        
  1873.  * RETURNS
  1874.  *  void
  1875.  *****************************************************************************/
  1876. void mmi_pen_MODIS_enqueue_up(S16 x, S16 y)
  1877. {
  1878.     /*----------------------------------------------------------------*/
  1879.     /* Local Variables                                                */
  1880.     /*----------------------------------------------------------------*/
  1881.     /*----------------------------------------------------------------*/
  1882.     /* Code Body                                                      */
  1883.     /*----------------------------------------------------------------*/
  1884.     mmi_pen_MODIS_enqueue_point(2, x, y);
  1885. }
  1886. /* By MMI thread */
  1887. #ifdef __MMI_HANDWRITING_PAD__
  1888. /*****************************************************************************
  1889.  * FUNCTION
  1890.  *  mmi_pen_draw_control_area
  1891.  * DESCRIPTION
  1892.  *  
  1893.  * PARAMETERS
  1894.  *  void
  1895.  * RETURNS
  1896.  *  void
  1897.  *****************************************************************************/
  1898. void mmi_pen_draw_control_area()
  1899. {
  1900.     /*----------------------------------------------------------------*/
  1901.     /* Local Variables                                                */
  1902.     /*----------------------------------------------------------------*/
  1903.     int i;
  1904.     /*----------------------------------------------------------------*/
  1905.     /* Code Body                                                      */
  1906.     /*----------------------------------------------------------------*/
  1907.     gui_lock_double_buffer();
  1908.     for (i = 0; i < TP_AREA_MAX_NUM; i++)
  1909.     {
  1910.         if (IS_ENABLE_FLAG(tp_area_table[i].flag, TP_CONTROL_AREA))
  1911.         {
  1912.             int index = 0;
  1913.             mmi_pen_point_struct pos1, pos2;
  1914.             pos1 = tp_area_table[i].pos[index];
  1915.             index++;
  1916.             while ((tp_area_table[i].pos[index].x != -1) && (tp_area_table[i].pos[index].y != -1))
  1917.             {
  1918.                 pos2 = tp_area_table[i].pos[index];
  1919.                 gdi_draw_line(pos1.x, pos1.y, pos2.x, pos2.y, GDI_COLOR_RED);
  1920.                 pos1 = pos2;
  1921.                 index++;
  1922.             }
  1923.             pos2 = tp_area_table[i].pos[0];
  1924.             gdi_draw_line(pos1.x, pos1.y, pos2.x, pos2.y, GDI_COLOR_RED);
  1925.         }
  1926.         else
  1927.         {
  1928.             /* handwriting area */
  1929.         }
  1930.     }
  1931.     gui_unlock_double_buffer();
  1932.     gui_BLT_double_buffer(0, 0, UI_device_width - 1, UI_device_height - 1);
  1933. }
  1934. #endif /* __MMI_HANDWRITING_PAD__ */ 
  1935. /*****************************************************************************
  1936.  * FUNCTION
  1937.  *  mmi_pen_MODIS_timer_hdlr
  1938.  * DESCRIPTION
  1939.  *  
  1940.  * PARAMETERS
  1941.  *  void
  1942.  * RETURNS
  1943.  *  void
  1944.  *****************************************************************************/
  1945. static void mmi_pen_MODIS_timer_hdlr(void)
  1946. {
  1947.     /*----------------------------------------------------------------*/
  1948.     /* Local Variables                                                */
  1949.     /*----------------------------------------------------------------*/
  1950.     mmi_pen_MODIS_queue_item_struct *pt, *pt_end;
  1951.     int new_head, saved_tail;
  1952.     MMI_BOOL has_events = MMI_FALSE;
  1953.     static MMI_BOOL entered = MMI_FALSE;
  1954.     /*----------------------------------------------------------------*/
  1955.     /* Code Body                                                      */
  1956.     /*----------------------------------------------------------------*/
  1957.     if (!g_pen_cntx.is_enabled)
  1958.     {
  1959.         g_mmi_pen_MODIS_qhead = g_mmi_pen_MODIS_qtail = 0;
  1960.         StartTimer(PEN_POLLING_TIMER, 20, mmi_pen_MODIS_timer_hdlr);
  1961.         return;
  1962.     }
  1963.     /* Avoid re-entrance of this function. Typically it's becuase NVRAM routines invoke timer 
  1964.        handler again */
  1965.     if (entered)
  1966.     {
  1967.         return;
  1968.     }
  1969.     entered = MMI_TRUE;
  1970.     g_mmi_pen_MODIS_timer_flag = MMI_TRUE;
  1971.     saved_tail = g_mmi_pen_MODIS_qtail;
  1972.     pt = g_mmi_pen_MODIS_queue + g_mmi_pen_MODIS_qhead;
  1973.     if (saved_tail < g_mmi_pen_MODIS_qhead)
  1974.     {
  1975.         pt_end = g_mmi_pen_MODIS_queue + MMI_PEN_MODIS_QUEUE_SIZE;
  1976.         new_head = 0;
  1977.     }
  1978.     else
  1979.     {
  1980.         pt_end = g_mmi_pen_MODIS_queue + saved_tail;
  1981.         new_head = saved_tail;
  1982.     }
  1983.     if (pt < pt_end)
  1984.     {
  1985.         has_events = MMI_TRUE;
  1986.     }
  1987.     while (pt < pt_end)
  1988.     {
  1989.     #ifdef __MMI_SCREEN_ROTATE__
  1990.         if (mmi_frm_get_screen_rotate() != MMI_FRM_SCREEN_ROTATE_0)
  1991.         {
  1992.             S32 tmp_x = pt->x, tmp_y = pt->y;
  1993.             /* W06.04 Replace functions for GDI LCD Rotate */
  1994.             gdi_rotate_map_absolute_hw_to_lcd(&tmp_x, &tmp_y);
  1995.             /* gdi_layer_map_rotated_coordinates(gdi_layer_get_base_layer_rotation(), &tmp_x, &tmp_y); */
  1996.             pt->x = (S16) tmp_x;
  1997.             pt->y = (S16) tmp_y;
  1998.         }
  1999.     #endif /* __MMI_SCREEN_ROTATE__ */ 
  2000.         switch (pt->type)
  2001.         {
  2002.             case 0:
  2003.                 mmi_pen_simulator_button_down_hdlr(pt->x, pt->y);
  2004.                 break;
  2005.             case 1:
  2006.                 mmi_pen_simulator_button_move_hdlr(pt->x, pt->y);
  2007.                 break;
  2008.             case 2:
  2009.                 mmi_pen_simulator_button_up_hdlr(pt->x, pt->y);
  2010.                 break;
  2011.             default:
  2012.                 ASSERT(0);
  2013.         }
  2014.         pt++;
  2015.         if (!g_mmi_pen_MODIS_timer_flag)
  2016.         {
  2017.             break;  /* mmi_pen_reset was invoked */
  2018.         }
  2019.     }
  2020.     /* Update queue when no mmi_pen_disable() and mmi_pen_reset() inside previous pen handler */
  2021.     if (g_mmi_pen_MODIS_timer_flag)
  2022.     {
  2023.         g_mmi_pen_MODIS_qhead = new_head;
  2024.     }
  2025.     g_mmi_pen_MODIS_timer_flag = MMI_FALSE;
  2026.     if (has_events)
  2027.     {
  2028.         TurnOnBacklight(MMI_TRUE);
  2029.     #ifdef __MMI_LCD_PARTIAL_ON__
  2030.         /* Switch screen and flush pen events */
  2031.         LeavePartialOnScreenSaverIfOk();
  2032.     #endif /* __MMI_LCD_PARTIAL_ON__ */ 
  2033.     }
  2034. #ifdef __MMI_HANDWRITING_PAD__
  2035.     mmi_pen_draw_control_area();
  2036. #endif 
  2037.     StartTimer(PEN_POLLING_TIMER, 20, mmi_pen_MODIS_timer_hdlr);
  2038.     entered = MMI_FALSE;
  2039. }
  2040. /*****************************************************************************
  2041.  * FUNCTION
  2042.  *  mmi_pen_MODIS_flush_queue
  2043.  * DESCRIPTION
  2044.  *  
  2045.  * PARAMETERS
  2046.  *  void
  2047.  * RETURNS
  2048.  *  void
  2049.  *****************************************************************************/
  2050. static void mmi_pen_MODIS_flush_queue(void)
  2051. {
  2052.     /*----------------------------------------------------------------*/
  2053.     /* Local Variables                                                */
  2054.     /*----------------------------------------------------------------*/
  2055.     /*----------------------------------------------------------------*/
  2056.     /* Code Body                                                      */
  2057.     /*----------------------------------------------------------------*/
  2058.     g_mmi_pen_MODIS_qtail = 0;
  2059.     g_mmi_pen_MODIS_qhead = 0;
  2060.     g_mmi_pen_MODIS_timer_flag = MMI_FALSE;
  2061. }
  2062. /*****************************************************************************
  2063.  * FUNCTION
  2064.  *  mmi_pen_MODIS_start_timer
  2065.  * DESCRIPTION
  2066.  *  
  2067.  * PARAMETERS
  2068.  *  void
  2069.  * RETURNS
  2070.  *  void
  2071.  *****************************************************************************/
  2072. static void mmi_pen_MODIS_start_timer(void)
  2073. {
  2074.     /*----------------------------------------------------------------*/
  2075.     /* Local Variables                                                */
  2076.     /*----------------------------------------------------------------*/
  2077.     /*----------------------------------------------------------------*/
  2078.     /* Code Body                                                      */
  2079.     /*----------------------------------------------------------------*/
  2080.     StartTimer(PEN_POLLING_TIMER, 20, mmi_pen_MODIS_timer_hdlr);
  2081. }
  2082. /*****************************************************************************
  2083.  * FUNCTION
  2084.  *  mmi_pen_MODIS_tp_ind
  2085.  * DESCRIPTION
  2086.  *  
  2087.  * PARAMETERS
  2088.  *  param       [IN]        unused
  2089.  * RETURNS
  2090.  *  void
  2091.  *****************************************************************************/
  2092. static void mmi_pen_MODIS_tp_ind(void *param /* unused */ )
  2093. {
  2094.     /*----------------------------------------------------------------*/
  2095.     /* Local Variables                                                */
  2096.     /*----------------------------------------------------------------*/
  2097.     /*----------------------------------------------------------------*/
  2098.     /* Code Body                                                      */
  2099.     /*----------------------------------------------------------------*/
  2100.     mmi_pen_MODIS_timer_hdlr();
  2101. }
  2102. #endif /* !defined(MMI_ON_WIN32) */ 
  2103. /****************************************************************
  2104.  * Unit test
  2105.  ***************************************************************/
  2106. #ifdef MMI_PEN_UNIT_TEST
  2107. /*
  2108.  * The simple drawing application is not efficent in order 
  2109.  * * to follow PC Simualator architecture 
  2110.  */
  2111. #include "wgui_categories.h"
  2112. #include "GlobalDefs.h"
  2113. #include "HistoryGprot.h"
  2114. static mmi_pen_point_struct mmi_pen_test_last_pos;
  2115. static U8 mmi_pen_draw_buffer[LCD_WIDTH * LCD_HEIGHT / 8];