1 /**************************************************************************/
2 /*                                                                        */
3 /*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4 /*                                                                        */
5 /*       This software is licensed under the Microsoft Software License   */
6 /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7 /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8 /*       and in the root directory of this software.                      */
9 /*                                                                        */
10 /**************************************************************************/
11 
12 
13 /**************************************************************************/
14 /**************************************************************************/
15 /**                                                                       */
16 /** GUIX Component                                                        */
17 /**                                                                       */
18 /**   Multi Line Text Input Management (Multi Line Text Input)            */
19 /**                                                                       */
20 /**************************************************************************/
21 
22 #define GX_SOURCE_CODE
23 
24 
25 /* Include necessary system files.  */
26 
27 #include "gx_api.h"
28 #include "gx_system.h"
29 #include "gx_window.h"
30 #include "gx_widget.h"
31 #include "gx_multi_line_text_input.h"
32 #include "gx_multi_line_text_view.h"
33 #include "gx_text_input_cursor.h"
34 
35 /**************************************************************************/
36 /*                                                                        */
37 /*  FUNCTION                                               RELEASE        */
38 /*                                                                        */
39 /*    _gx_multi_line_text_input_pen_down_process          PORTABLE C      */
40 /*                                                           6.1          */
41 /*  AUTHOR                                                                */
42 /*                                                                        */
43 /*    Kenneth Maxwell, Microsoft Corporation                              */
44 /*                                                                        */
45 /*  DESCRIPTION                                                           */
46 /*                                                                        */
47 /*    This function handles pen down event for multi line text input      */
48 /*    widget.                                                             */
49 /*                                                                        */
50 /*  INPUT                                                                 */
51 /*                                                                        */
52 /*    text_input                            Multi-line text input widget  */
53 /*                                            control block               */
54 /*    event_ptr                             Pointer to GX_EVENT structure */
55 /*                                                                        */
56 /*  OUTPUT                                                                */
57 /*                                                                        */
58 /*    status                                Completion status             */
59 /*                                                                        */
60 /*  CALLS                                                                 */
61 /*                                                                        */
62 /*    _gx_system_input_capture              Direct all input events to    */
63 /*                                            specified widget            */
64 /*    _gx_multi_line_text_input_highlight_rectangle_get                   */
65 /*                                          Retrieve rectangle of         */
66 /*                                            highlight text              */
67 /*    _gx_text_input_cursor_dirty_rectangle_get                           */
68 /*                                          Retrieve cursor rectangle     */
69 /*    _gx_multi_line_text_input_cursor_pos_calculate                      */
70 /*                                          Update text insert position   */
71 /*    _gx_system_dirty_partial_add          Mark the partial area of a    */
72 /*                                            widget as dirty             */
73 /*    _gx_system_dirty_mark                 Mark specified widget dirty   */
74 /*    _gx_window_event_process              Default window event process  */
75 /*                                                                        */
76 /*  CALLED BY                                                             */
77 /*                                                                        */
78 /*    _gx_multi_line_text_input_event_process                             */
79 /*                                                                        */
80 /*  RELEASE HISTORY                                                       */
81 /*                                                                        */
82 /*    DATE              NAME                      DESCRIPTION             */
83 /*                                                                        */
84 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
85 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
86 /*                                            resulting in version 6.1    */
87 /*                                                                        */
88 /**************************************************************************/
_gx_multi_line_text_input_pen_down_process(GX_MULTI_LINE_TEXT_INPUT * text_input,GX_EVENT * event_ptr)89 static UINT _gx_multi_line_text_input_pen_down_process(GX_MULTI_LINE_TEXT_INPUT *text_input, GX_EVENT *event_ptr)
90 {
91 GX_TEXT_INPUT_CURSOR *cursor_ptr = &text_input -> gx_multi_line_text_input_cursor_instance;
92 INT                   scroll_shift;
93 GX_RECTANGLE          cursor_rect;
94 UINT                  start_mark = text_input -> gx_multi_line_text_input_start_mark;
95 UINT                  end_mark = text_input -> gx_multi_line_text_input_end_mark;
96 
97     _gx_system_input_capture((GX_WIDGET *)text_input);
98 
99     scroll_shift = text_input -> gx_multi_line_text_view_text_scroll_shift;
100 
101     if (start_mark != end_mark)
102     {
103         _gx_multi_line_text_input_highlight_rectangle_get(text_input, &cursor_rect);
104     }
105     else
106     {
107         /* Record cursor rectangle and scroll shift value before recaculate cursor position. */
108         _gx_text_input_cursor_dirty_rectangle_get(cursor_ptr, &cursor_rect);
109     }
110 
111     /* Calculate cursor position according to click position. */
112     _gx_multi_line_text_input_cursor_pos_calculate(text_input, (*event_ptr).gx_event_payload.gx_event_pointdata);
113 
114     /* Set highlight start/end mark to insert position. */
115     text_input -> gx_multi_line_text_input_start_mark = text_input -> gx_multi_line_text_input_text_insert_position;
116     text_input -> gx_multi_line_text_input_end_mark = text_input -> gx_multi_line_text_input_text_insert_position;
117 
118     if (scroll_shift != text_input -> gx_multi_line_text_view_text_scroll_shift)
119     {
120         _gx_system_dirty_mark((GX_WIDGET *)text_input);
121     }
122     else
123     {
124         if (start_mark != end_mark)
125         {
126             /* Mark highlight area as dirty. */
127             _gx_system_dirty_partial_add((GX_WIDGET *)text_input, &cursor_rect);
128         }
129         else
130         {
131             _gx_system_dirty_partial_add((GX_WIDGET *)text_input, &cursor_rect);
132 
133             /* Get current cursor rectangle. */
134             _gx_text_input_cursor_dirty_rectangle_get(cursor_ptr, &cursor_rect);
135 
136             _gx_system_dirty_partial_add((GX_WIDGET *)text_input, &cursor_rect);
137         }
138     }
139 
140     return _gx_window_event_process((GX_WINDOW *)text_input, event_ptr);
141 }
142 
143 
144 /**************************************************************************/
145 /*                                                                        */
146 /*  FUNCTION                                               RELEASE        */
147 /*                                                                        */
148 /*    _gx_multi_line_text_input_pen_drag_process          PORTABLE C      */
149 /*                                                           6.1          */
150 /*  AUTHOR                                                                */
151 /*                                                                        */
152 /*    Kenneth Maxwell, Microsoft Corporation                              */
153 /*                                                                        */
154 /*  DESCRIPTION                                                           */
155 /*                                                                        */
156 /*    This function handles pen drag event for multi line text input      */
157 /*    widget.                                                             */
158 /*                                                                        */
159 /*  INPUT                                                                 */
160 /*                                                                        */
161 /*    text_input                            Multi-line text input widget  */
162 /*                                            control block               */
163 /*    event_ptr                             Pointer to GX_EVENT structure */
164 /*                                                                        */
165 /*  OUTPUT                                                                */
166 /*                                                                        */
167 /*    status                                Completion status             */
168 /*                                                                        */
169 /*  CALLS                                                                 */
170 /*                                                                        */
171 /*    _gx_text_input_cursor_dirty_rectangle_get                           */
172 /*                                          Retrieve cursor rectangle     */
173 /*    _gx_multi_line_text_input_text_rectangle_get                        */
174 /*                                          Retrieve text rectangle       */
175 /*                                            between specified position  */
176 /*    _gx_multi_line_text_input_cursor_pos_calculate                      */
177 /*                                          Update text insert position   */
178 /*    _gx_system_dirty_partial_add          Mark the partial area of a    */
179 /*                                            widget as dirty             */
180 /*    _gx_system_timer_start                Start a timer                 */
181 /*    _gx_system_timer_stop                 Stop a timer                  */
182 /*    _gx_windwo_event_process              Default window event process  */
183 /*                                                                        */
184 /*  CALLED BY                                                             */
185 /*                                                                        */
186 /*    _gx_multi_line_text_input_event_process                             */
187 /*                                                                        */
188 /*  RELEASE HISTORY                                                       */
189 /*                                                                        */
190 /*    DATE              NAME                      DESCRIPTION             */
191 /*                                                                        */
192 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
193 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
194 /*                                            resulting in version 6.1    */
195 /*                                                                        */
196 /**************************************************************************/
_gx_multi_line_text_input_pen_drag_process(GX_MULTI_LINE_TEXT_INPUT * text_input,GX_EVENT * event_ptr)197 static UINT _gx_multi_line_text_input_pen_drag_process(GX_MULTI_LINE_TEXT_INPUT *text_input, GX_EVENT *event_ptr)
198 {
199 GX_TEXT_INPUT_CURSOR *cursor_ptr = &text_input -> gx_multi_line_text_input_cursor_instance;
200 INT                   scroll_shift;
201 GX_RECTANGLE          cursor_rect;
202 GX_POINT              start_pos;
203 UINT                  old_end_mark;
204 GX_RECTANGLE          client;
205 GX_POINT              click_pos;
206 GX_VALUE              click_y;
207 
208     if (text_input -> gx_widget_status & GX_STATUS_OWNS_INPUT)
209     {
210         client = text_input -> gx_window_client;
211 
212         click_pos = event_ptr -> gx_event_payload.gx_event_pointdata;
213         click_y = click_pos.gx_point_y;
214 
215         if (text_input -> gx_multi_line_text_input_start_mark == text_input -> gx_multi_line_text_input_end_mark)
216         {
217             _gx_text_input_cursor_dirty_rectangle_get(cursor_ptr, &cursor_rect);
218 
219             /* Mark cursor area as dirty. */
220             _gx_system_dirty_partial_add((GX_WIDGET *)text_input, &cursor_rect);
221         }
222 
223         start_pos = cursor_ptr -> gx_text_input_cursor_pos;
224 
225         scroll_shift = text_input -> gx_multi_line_text_view_text_scroll_shift;
226         old_end_mark = text_input -> gx_multi_line_text_input_end_mark;
227 
228         if (click_pos.gx_point_y < client.gx_rectangle_top)
229         {
230             click_pos.gx_point_y = client.gx_rectangle_top;
231         }
232         else if (click_pos.gx_point_y > client.gx_rectangle_bottom)
233         {
234             click_pos.gx_point_y = client.gx_rectangle_bottom;
235         }
236         _gx_multi_line_text_input_cursor_pos_calculate(text_input, click_pos);
237 
238         text_input -> gx_multi_line_text_input_end_mark = text_input -> gx_multi_line_text_input_text_insert_position;
239 
240         if ((click_y < client.gx_rectangle_top) &&
241             (text_input -> gx_multi_line_text_input_text_cursor_line > 1))
242         {
243             if (!(text_input -> gx_widget_status & (GX_STATUS_MARK_NEXT | GX_STATUS_MARK_PREVIOUS)))
244             {
245                 /* Start a timer to move text right. */
246                 _gx_system_timer_start((GX_WIDGET *)text_input, GX_MARK_TIMER,
247                                        GX_MARK_INTERVAL, GX_MARK_INTERVAL);
248             }
249 
250             text_input -> gx_widget_status &= ~GX_STATUS_MARK_NEXT;
251             text_input -> gx_widget_status |= GX_STATUS_MARK_PREVIOUS;
252         }
253         else if ((click_y > client.gx_rectangle_bottom) &&
254                  (text_input -> gx_multi_line_text_input_text_cursor_line < text_input -> gx_multi_line_text_view_text_total_rows))
255         {
256             if (!(text_input -> gx_widget_status & (GX_STATUS_MARK_NEXT | GX_STATUS_MARK_PREVIOUS)))
257             {
258                 /* Start a timer to move text left. */
259                 _gx_system_timer_start((GX_WIDGET *)text_input, GX_MARK_TIMER,
260                                        GX_MARK_INTERVAL, GX_MARK_INTERVAL);
261             }
262 
263             text_input -> gx_widget_status &= ~GX_STATUS_MARK_PREVIOUS;
264             text_input -> gx_widget_status |= GX_STATUS_MARK_NEXT;
265         }
266         else
267         {
268             if (text_input -> gx_widget_status & (GX_STATUS_MARK_NEXT | GX_STATUS_MARK_PREVIOUS))
269             {
270                 _gx_system_timer_stop((GX_WIDGET *)text_input, GX_MARK_TIMER);
271                 text_input -> gx_widget_status &= ~(GX_STATUS_MARK_NEXT | GX_STATUS_MARK_PREVIOUS);
272             }
273         }
274 
275         if (scroll_shift != text_input -> gx_multi_line_text_view_text_scroll_shift)
276         {
277             _gx_system_dirty_mark((GX_WIDGET *)text_input);
278         }
279         else
280         {
281             if ((text_input -> gx_multi_line_text_input_start_mark != text_input -> gx_multi_line_text_input_end_mark) ||
282                 (text_input -> gx_multi_line_text_input_start_mark != old_end_mark))
283             {
284                 _gx_multi_line_text_input_text_rectangle_get(text_input,
285                                                              start_pos,
286                                                              cursor_ptr -> gx_text_input_cursor_pos, &cursor_rect);
287 
288                 /* Mark highlight area as dirty. */
289                 _gx_system_dirty_partial_add((GX_WIDGET *)text_input, &cursor_rect);
290             }
291         }
292     }
293     else
294     {
295         _gx_window_event_process((GX_WINDOW *)text_input, event_ptr);
296     }
297 
298     return GX_SUCCESS;
299 }
300 
301 /**************************************************************************/
302 /*                                                                        */
303 /*  FUNCTION                                               RELEASE        */
304 /*                                                                        */
305 /*    _gx_multi_line_text_input_event_process             PORTABLE C      */
306 /*                                                           6.1.3        */
307 /*  AUTHOR                                                                */
308 /*                                                                        */
309 /*    Kenneth Maxwell, Microsoft Corporation                              */
310 /*                                                                        */
311 /*  DESCRIPTION                                                           */
312 /*                                                                        */
313 /*    This function processes events for the specified text input widget. */
314 /*                                                                        */
315 /*  INPUT                                                                 */
316 /*                                                                        */
317 /*    text_input                            Multi line text input         */
318 /*                                            control block               */
319 /*    event_ptr                             Incoming event to process     */
320 /*                                                                        */
321 /*  OUTPUT                                                                */
322 /*                                                                        */
323 /*    status                                Completion status             */
324 /*                                                                        */
325 /*  CALLS                                                                 */
326 /*                                                                        */
327 /*    _gx_widget_event_process              Default widget event process  */
328 /*    _gx_system_timer_start                Allocate a free timer and     */
329 /*                                          activates it                  */
330 /*    _gx_system_timer_stop                 Stop an active GUIX timer     */
331 /*    _gx_multi_line_text_input_keydown_process                           */
332 /*                                          Process the keydown event     */
333 /*    _gx_widget_event_generate             Generate an event             */
334 /*    _gx_text_input_cursor_dirty_rectangle_get                           */
335 /*                                          Get cursor rectangle          */
336 /*    _gx_multi_line_text_input_cursor_pos_calculate                      */
337 /*                                          Calculate cursor position     */
338 /*                                            according to click positin  */
339 /*    _gx_multi_line_text_input_cursor_pos_update                         */
340 /*                                          Update cursor position        */
341 /*                                            according to insert position*/
342 /*    _gx_system_dirty_partial_add          Add a dirty area to the       */
343 /*                                            specified widget            */
344 /*    _gx_multi_line_text_view_event_process                              */
345 /*                                          Invoke the text view event    */
346 /*                                            process routine             */
347 /*                                                                        */
348 /*  CALLED BY                                                             */
349 /*                                                                        */
350 /*    Application Code                                                    */
351 /*    GUIX Internal Code                                                  */
352 /*                                                                        */
353 /*  RELEASE HISTORY                                                       */
354 /*                                                                        */
355 /*    DATE              NAME                      DESCRIPTION             */
356 /*                                                                        */
357 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
358 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
359 /*                                            resulting in version 6.1    */
360 /*  12-31-2020     Kenneth Maxwell          Modified comment(s),          */
361 /*                                            added logic to release      */
362 /*                                            dynamic input buffer,       */
363 /*                                            resulting in version 6.1.3  */
364 /*                                                                        */
365 /**************************************************************************/
_gx_multi_line_text_input_event_process(GX_MULTI_LINE_TEXT_INPUT * text_input,GX_EVENT * event_ptr)366 UINT  _gx_multi_line_text_input_event_process(GX_MULTI_LINE_TEXT_INPUT *text_input, GX_EVENT *event_ptr)
367 {
368 GX_TEXT_INPUT_CURSOR    *cursor_ptr = &text_input -> gx_multi_line_text_input_cursor_instance;
369 GX_MULTI_LINE_TEXT_VIEW *view = (GX_MULTI_LINE_TEXT_VIEW *)text_input;
370 GX_WIDGET               *widget = (GX_WIDGET *)text_input;
371 GX_VALUE                 blink_interval = text_input -> gx_multi_line_text_input_cursor_instance.gx_text_input_cursor_blink_interval;
372 UINT                     status;
373 GX_RECTANGLE             cursor_rect;
374 INT                      scroll_shift;
375 ULONG                    old_style;
376 
377     /* Default status to success.  */
378     status =  GX_SUCCESS;
379 
380     /* Process relative to the type of event.  */
381     switch (event_ptr -> gx_event_type)
382     {
383     case GX_EVENT_SHOW:
384         _gx_window_event_process((GX_WINDOW *)text_input, event_ptr);
385 
386         /* Update cursor position. */
387         _gx_multi_line_text_input_cursor_pos_update(text_input, GX_TRUE);
388 
389         if ((text_input -> gx_widget_style & GX_STYLE_CURSOR_ALWAYS) &&
390             (text_input -> gx_widget_style & GX_STYLE_CURSOR_BLINK))
391         {
392             /* Start the timer.  */
393             _gx_system_timer_start(widget, ID_TEXT_INPUT_TIMER, GX_CURSOR_BLINK_INTERVAL, GX_CURSOR_BLINK_INTERVAL);
394         }
395 
396         /* Get visible rows. */
397         _gx_multi_line_text_view_visible_rows_compute((GX_MULTI_LINE_TEXT_VIEW *)text_input);
398         break;
399 
400     case GX_EVENT_STYLE_CHANGED:
401         if (widget -> gx_widget_status & GX_STATUS_VISIBLE)
402         {
403             _gx_multi_line_text_view_event_process((GX_MULTI_LINE_TEXT_VIEW *)text_input, event_ptr);
404 
405             old_style = event_ptr -> gx_event_payload.gx_event_ulongdata;
406             if ((old_style & (GX_STYLE_BORDER_MASK | GX_STYLE_TEXT_ALIGNMENT_MASK)) !=
407                 (widget -> gx_widget_style & (GX_STYLE_BORDER_MASK | GX_STYLE_TEXT_ALIGNMENT_MASK)))
408             {
409                 text_input -> gx_multi_line_text_view_line_index_old = GX_TRUE;
410             }
411         }
412         break;
413 
414     case GX_EVENT_FOCUS_GAINED:
415         /* Call the widget default processing. */
416         _gx_widget_event_process(widget, event_ptr);
417 
418         /* Do not do anything if the CURSOR_ALWAYS flag is set. */
419         if (!(text_input -> gx_widget_style & GX_STYLE_CURSOR_ALWAYS))
420         {
421             text_input -> gx_widget_status |= (GX_STATUS_CURSOR_SHOW | GX_STATUS_CURSOR_DRAW);
422 
423             if (text_input -> gx_widget_style & GX_STYLE_CURSOR_BLINK)
424             {
425                 /* Start the timer.  */
426                 _gx_system_timer_start(widget, ID_TEXT_INPUT_TIMER, (UINT)blink_interval, (UINT)blink_interval);
427             }
428         }
429 
430         _gx_multi_line_text_input_text_select(text_input, 0, text_input -> gx_multi_line_text_view_text.gx_string_length - 1);
431         break;
432 
433     case GX_EVENT_KEY_DOWN:
434         _gx_multi_line_text_input_keydown_process(text_input, event_ptr);
435         if (widget -> gx_widget_style & GX_STYLE_TEXT_INPUT_NOTIFY_ALL)
436         {
437             _gx_widget_event_generate(widget, GX_EVENT_TEXT_EDITED, 0);
438         }
439         break;
440 
441     case GX_EVENT_PEN_DOWN:
442         _gx_multi_line_text_input_pen_down_process(text_input, event_ptr);
443         break;
444 
445     case GX_EVENT_PEN_DRAG:
446         _gx_multi_line_text_input_pen_drag_process(text_input, event_ptr);
447         break;
448 
449     case GX_EVENT_PEN_UP:
450         if (text_input -> gx_widget_status & GX_STATUS_OWNS_INPUT)
451         {
452             _gx_system_input_release((GX_WIDGET *)text_input);
453 
454             if (text_input -> gx_widget_status & (GX_STATUS_MARK_NEXT | GX_STATUS_MARK_PREVIOUS))
455             {
456                 _gx_system_timer_stop((GX_WIDGET *)text_input, GX_MARK_TIMER);
457                 text_input -> gx_widget_status &= ~(GX_STATUS_MARK_NEXT | GX_STATUS_MARK_PREVIOUS);
458             }
459         }
460         else
461         {
462             _gx_window_event_process((GX_WINDOW *)text_input, event_ptr);
463         }
464         break;
465 
466     case GX_EVENT_TIMER:
467         if (event_ptr -> gx_event_payload.gx_event_timer_id == GX_MARK_TIMER)
468         {
469             if (text_input -> gx_widget_status & GX_STATUS_MARK_PREVIOUS)
470             {
471                 _gx_multi_line_text_input_mark_up(text_input);
472             }
473             else
474             {
475                 _gx_multi_line_text_input_mark_down(text_input);
476             }
477         }
478         else if ((event_ptr -> gx_event_payload.gx_event_timer_id == ID_TEXT_INPUT_TIMER) &&
479                  (text_input -> gx_widget_status & GX_STATUS_CURSOR_SHOW) &&
480                  (text_input -> gx_multi_line_text_input_start_mark == text_input -> gx_multi_line_text_input_end_mark))
481         {
482             if (text_input -> gx_widget_status & GX_STATUS_CURSOR_DRAW)
483             {
484                 text_input -> gx_widget_status &= (ULONG)(~GX_STATUS_CURSOR_DRAW);
485             }
486             else
487             {
488                 text_input -> gx_widget_status |= GX_STATUS_CURSOR_DRAW;
489             }
490             /* Define a cursor rectangle for the cursor. */
491             _gx_text_input_cursor_dirty_rectangle_get(&text_input -> gx_multi_line_text_input_cursor_instance, &cursor_rect);
492             _gx_system_dirty_partial_add(widget, &cursor_rect);
493         }
494         break;
495 
496     case GX_EVENT_FOCUS_LOST:
497         _gx_widget_event_process(widget, event_ptr);
498 
499         /* Do not do anything if the CURSOR_ALWAYS flag is set. */
500         if (!(text_input -> gx_widget_style & GX_STYLE_CURSOR_ALWAYS))
501         {
502             text_input ->  gx_widget_status &= (ULONG)(~GX_STATUS_CURSOR_SHOW);
503 
504             /* Stop the timer if the cursor style is BLINK. */
505             if (text_input -> gx_widget_style & GX_STYLE_CURSOR_BLINK)
506             {
507                 /* Stop the timer. */
508                 _gx_system_timer_stop(widget, 0);
509             }
510 
511             /* Define a cursor rectangle for the cursor. */
512             _gx_text_input_cursor_dirty_rectangle_get(&text_input -> gx_multi_line_text_input_cursor_instance, &cursor_rect);
513             _gx_system_dirty_partial_add(widget, &cursor_rect);
514         }
515 
516         if (text_input -> gx_multi_line_text_input_start_mark != text_input -> gx_multi_line_text_input_end_mark)
517         {
518             _gx_multi_line_text_input_highlight_rectangle_get(text_input, &cursor_rect);
519 
520             text_input -> gx_multi_line_text_input_start_mark = 0;
521             text_input -> gx_multi_line_text_input_end_mark = 0;
522 
523             _gx_system_dirty_partial_add(widget, &cursor_rect);
524         }
525 
526         if (text_input -> gx_multi_line_text_input_text_was_modified)
527         {
528             _gx_widget_event_generate(widget, GX_EVENT_TEXT_EDITED, 0);
529             text_input -> gx_multi_line_text_input_text_was_modified = GX_FALSE;
530         }
531         break;
532 
533     case GX_EVENT_VERTICAL_SCROLL:
534         /* Pick up scroll shift value. */
535         scroll_shift = event_ptr -> gx_event_payload.gx_event_intdata[1] - event_ptr -> gx_event_payload.gx_event_intdata[0];
536 
537         /* Move cursor position according to shift value. */
538         cursor_ptr -> gx_text_input_cursor_pos.gx_point_y = (GX_VALUE)(cursor_ptr -> gx_text_input_cursor_pos.gx_point_y + scroll_shift);
539 
540         /* Call the multi-line text view event processing. */
541         _gx_multi_line_text_view_event_process(view, event_ptr);
542         break;
543 
544     case GX_EVENT_LANGUAGE_CHANGE:
545         break;
546 
547     case GX_EVENT_COPY:
548         _gx_multi_line_text_input_copy(text_input);
549         break;
550 
551     case GX_EVENT_CUT:
552         _gx_multi_line_text_input_cut(text_input);
553         break;
554 
555     case GX_EVENT_PASTE:
556         _gx_multi_line_text_input_paste(text_input);
557         break;
558 
559     case GX_EVENT_MARK_NEXT:
560         _gx_multi_line_text_input_mark_next(text_input);
561         break;
562 
563     case GX_EVENT_MARK_PREVIOUS:
564         _gx_multi_line_text_input_mark_previous(text_input);
565         break;
566 
567     case GX_EVENT_MARK_UP:
568         _gx_multi_line_text_input_mark_up(text_input);
569         break;
570 
571     case GX_EVENT_MARK_DOWN:
572         _gx_multi_line_text_input_mark_down(text_input);
573         break;
574 
575     case GX_EVENT_MARK_END:
576         _gx_multi_line_text_input_mark_end(text_input);
577         break;
578 
579     case GX_EVENT_MARK_HOME:
580         _gx_multi_line_text_input_mark_home(text_input);
581         break;
582 
583     case GX_EVENT_DELETE:
584         if (text_input -> gx_widget_status & GX_STATUS_DYNAMIC_BUFFER)
585         {
586             if (!_gx_system_memory_free)
587             {
588                 return GX_SYSTEM_MEMORY_ERROR;
589             }
590 
591             _gx_system_memory_free((void *)text_input -> gx_multi_line_text_view_text.gx_string_ptr);
592             text_input -> gx_multi_line_text_view_text.gx_string_ptr = GX_NULL;
593         }
594         break;
595 
596     default:
597         /* Call the multi-line text view event processing.  */
598         status = _gx_multi_line_text_view_event_process(view, event_ptr);
599     }
600 
601     /* Return completion status.  */
602     return(status);
603 }
604 
605