GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_multi_line_text_input_event_process.c Lines: 186 186 100.0 %
Date: 2024-12-05 08:52:37 Branches: 98 98 100.0 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 *
4
 * This program and the accompanying materials are made available under the
5
 * terms of the MIT License which is available at
6
 * https://opensource.org/licenses/MIT.
7
 *
8
 * SPDX-License-Identifier: MIT
9
 **************************************************************************/
10
11
12
/**************************************************************************/
13
/**************************************************************************/
14
/**                                                                       */
15
/** GUIX Component                                                        */
16
/**                                                                       */
17
/**   Multi Line Text Input Management (Multi Line Text Input)            */
18
/**                                                                       */
19
/**************************************************************************/
20
21
#define GX_SOURCE_CODE
22
23
24
/* Include necessary system files.  */
25
26
#include "gx_api.h"
27
#include "gx_system.h"
28
#include "gx_window.h"
29
#include "gx_widget.h"
30
#include "gx_multi_line_text_input.h"
31
#include "gx_multi_line_text_view.h"
32
#include "gx_text_input_cursor.h"
33
34
/**************************************************************************/
35
/*                                                                        */
36
/*  FUNCTION                                               RELEASE        */
37
/*                                                                        */
38
/*    _gx_multi_line_text_input_pen_down_process          PORTABLE C      */
39
/*                                                           6.1          */
40
/*  AUTHOR                                                                */
41
/*                                                                        */
42
/*    Kenneth Maxwell, Microsoft Corporation                              */
43
/*                                                                        */
44
/*  DESCRIPTION                                                           */
45
/*                                                                        */
46
/*    This function handles pen down event for multi line text input      */
47
/*    widget.                                                             */
48
/*                                                                        */
49
/*  INPUT                                                                 */
50
/*                                                                        */
51
/*    text_input                            Multi-line text input widget  */
52
/*                                            control block               */
53
/*    event_ptr                             Pointer to GX_EVENT structure */
54
/*                                                                        */
55
/*  OUTPUT                                                                */
56
/*                                                                        */
57
/*    status                                Completion status             */
58
/*                                                                        */
59
/*  CALLS                                                                 */
60
/*                                                                        */
61
/*    _gx_system_input_capture              Direct all input events to    */
62
/*                                            specified widget            */
63
/*    _gx_multi_line_text_input_highlight_rectangle_get                   */
64
/*                                          Retrieve rectangle of         */
65
/*                                            highlight text              */
66
/*    _gx_text_input_cursor_dirty_rectangle_get                           */
67
/*                                          Retrieve cursor rectangle     */
68
/*    _gx_multi_line_text_input_cursor_pos_calculate                      */
69
/*                                          Update text insert position   */
70
/*    _gx_system_dirty_partial_add          Mark the partial area of a    */
71
/*                                            widget as dirty             */
72
/*    _gx_system_dirty_mark                 Mark specified widget dirty   */
73
/*    _gx_window_event_process              Default window event process  */
74
/*                                                                        */
75
/*  CALLED BY                                                             */
76
/*                                                                        */
77
/*    _gx_multi_line_text_input_event_process                             */
78
/*                                                                        */
79
/*  RELEASE HISTORY                                                       */
80
/*                                                                        */
81
/*    DATE              NAME                      DESCRIPTION             */
82
/*                                                                        */
83
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
84
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
85
/*                                            resulting in version 6.1    */
86
/*                                                                        */
87
/**************************************************************************/
88
1018
static UINT _gx_multi_line_text_input_pen_down_process(GX_MULTI_LINE_TEXT_INPUT *text_input, GX_EVENT *event_ptr)
89
{
90
1018
GX_TEXT_INPUT_CURSOR *cursor_ptr = &text_input -> gx_multi_line_text_input_cursor_instance;
91
INT                   scroll_shift;
92
GX_RECTANGLE          cursor_rect;
93
1018
UINT                  start_mark = text_input -> gx_multi_line_text_input_start_mark;
94
1018
UINT                  end_mark = text_input -> gx_multi_line_text_input_end_mark;
95
96
1018
    _gx_system_input_capture((GX_WIDGET *)text_input);
97
98
1018
    scroll_shift = text_input -> gx_multi_line_text_view_text_scroll_shift;
99
100
1018
    if (start_mark != end_mark)
101
    {
102
232
        _gx_multi_line_text_input_highlight_rectangle_get(text_input, &cursor_rect);
103
    }
104
    else
105
    {
106
        /* Record cursor rectangle and scroll shift value before recaculate cursor position. */
107
786
        _gx_text_input_cursor_dirty_rectangle_get(cursor_ptr, &cursor_rect);
108
    }
109
110
    /* Calculate cursor position according to click position. */
111
1018
    _gx_multi_line_text_input_cursor_pos_calculate(text_input, (*event_ptr).gx_event_payload.gx_event_pointdata);
112
113
    /* Set highlight start/end mark to insert position. */
114
1018
    text_input -> gx_multi_line_text_input_start_mark = text_input -> gx_multi_line_text_input_text_insert_position;
115
1018
    text_input -> gx_multi_line_text_input_end_mark = text_input -> gx_multi_line_text_input_text_insert_position;
116
117
1018
    if (scroll_shift != text_input -> gx_multi_line_text_view_text_scroll_shift)
118
    {
119
3
        _gx_system_dirty_mark((GX_WIDGET *)text_input);
120
    }
121
    else
122
    {
123
1015
        if (start_mark != end_mark)
124
        {
125
            /* Mark highlight area as dirty. */
126
232
            _gx_system_dirty_partial_add((GX_WIDGET *)text_input, &cursor_rect);
127
        }
128
        else
129
        {
130
783
            _gx_system_dirty_partial_add((GX_WIDGET *)text_input, &cursor_rect);
131
132
            /* Get current cursor rectangle. */
133
783
            _gx_text_input_cursor_dirty_rectangle_get(cursor_ptr, &cursor_rect);
134
135
783
            _gx_system_dirty_partial_add((GX_WIDGET *)text_input, &cursor_rect);
136
        }
137
    }
138
139
1018
    return _gx_window_event_process((GX_WINDOW *)text_input, event_ptr);
140
}
141
142
143
/**************************************************************************/
144
/*                                                                        */
145
/*  FUNCTION                                               RELEASE        */
146
/*                                                                        */
147
/*    _gx_multi_line_text_input_pen_drag_process          PORTABLE C      */
148
/*                                                           6.1          */
149
/*  AUTHOR                                                                */
150
/*                                                                        */
151
/*    Kenneth Maxwell, Microsoft Corporation                              */
152
/*                                                                        */
153
/*  DESCRIPTION                                                           */
154
/*                                                                        */
155
/*    This function handles pen drag event for multi line text input      */
156
/*    widget.                                                             */
157
/*                                                                        */
158
/*  INPUT                                                                 */
159
/*                                                                        */
160
/*    text_input                            Multi-line text input widget  */
161
/*                                            control block               */
162
/*    event_ptr                             Pointer to GX_EVENT structure */
163
/*                                                                        */
164
/*  OUTPUT                                                                */
165
/*                                                                        */
166
/*    status                                Completion status             */
167
/*                                                                        */
168
/*  CALLS                                                                 */
169
/*                                                                        */
170
/*    _gx_text_input_cursor_dirty_rectangle_get                           */
171
/*                                          Retrieve cursor rectangle     */
172
/*    _gx_multi_line_text_input_text_rectangle_get                        */
173
/*                                          Retrieve text rectangle       */
174
/*                                            between specified position  */
175
/*    _gx_multi_line_text_input_cursor_pos_calculate                      */
176
/*                                          Update text insert position   */
177
/*    _gx_system_dirty_partial_add          Mark the partial area of a    */
178
/*                                            widget as dirty             */
179
/*    _gx_system_timer_start                Start a timer                 */
180
/*    _gx_system_timer_stop                 Stop a timer                  */
181
/*    _gx_windwo_event_process              Default window event process  */
182
/*                                                                        */
183
/*  CALLED BY                                                             */
184
/*                                                                        */
185
/*    _gx_multi_line_text_input_event_process                             */
186
/*                                                                        */
187
/*  RELEASE HISTORY                                                       */
188
/*                                                                        */
189
/*    DATE              NAME                      DESCRIPTION             */
190
/*                                                                        */
191
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
192
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
193
/*                                            resulting in version 6.1    */
194
/*                                                                        */
195
/**************************************************************************/
196
23
static UINT _gx_multi_line_text_input_pen_drag_process(GX_MULTI_LINE_TEXT_INPUT *text_input, GX_EVENT *event_ptr)
197
{
198
23
GX_TEXT_INPUT_CURSOR *cursor_ptr = &text_input -> gx_multi_line_text_input_cursor_instance;
199
INT                   scroll_shift;
200
GX_RECTANGLE          cursor_rect;
201
GX_POINT              start_pos;
202
UINT                  old_end_mark;
203
GX_RECTANGLE          client;
204
GX_POINT              click_pos;
205
GX_VALUE              click_y;
206
207
23
    if (text_input -> gx_widget_status & GX_STATUS_OWNS_INPUT)
208
    {
209
21
        client = text_input -> gx_window_client;
210
211
21
        click_pos = event_ptr -> gx_event_payload.gx_event_pointdata;
212
21
        click_y = click_pos.gx_point_y;
213
214
21
        if (text_input -> gx_multi_line_text_input_start_mark == text_input -> gx_multi_line_text_input_end_mark)
215
        {
216
10
            _gx_text_input_cursor_dirty_rectangle_get(cursor_ptr, &cursor_rect);
217
218
            /* Mark cursor area as dirty. */
219
10
            _gx_system_dirty_partial_add((GX_WIDGET *)text_input, &cursor_rect);
220
        }
221
222
21
        start_pos = cursor_ptr -> gx_text_input_cursor_pos;
223
224
21
        scroll_shift = text_input -> gx_multi_line_text_view_text_scroll_shift;
225
21
        old_end_mark = text_input -> gx_multi_line_text_input_end_mark;
226
227
21
        if (click_pos.gx_point_y < client.gx_rectangle_top)
228
        {
229
6
            click_pos.gx_point_y = client.gx_rectangle_top;
230
        }
231
15
        else if (click_pos.gx_point_y > client.gx_rectangle_bottom)
232
        {
233
5
            click_pos.gx_point_y = client.gx_rectangle_bottom;
234
        }
235
21
        _gx_multi_line_text_input_cursor_pos_calculate(text_input, click_pos);
236
237
21
        text_input -> gx_multi_line_text_input_end_mark = text_input -> gx_multi_line_text_input_text_insert_position;
238
239
21
        if ((click_y < client.gx_rectangle_top) &&
240
6
            (text_input -> gx_multi_line_text_input_text_cursor_line > 1))
241
        {
242
4
            if (!(text_input -> gx_widget_status & (GX_STATUS_MARK_NEXT | GX_STATUS_MARK_PREVIOUS)))
243
            {
244
                /* Start a timer to move text right. */
245
3
                _gx_system_timer_start((GX_WIDGET *)text_input, GX_MARK_TIMER,
246
                                       GX_MARK_INTERVAL, GX_MARK_INTERVAL);
247
            }
248
249
4
            text_input -> gx_widget_status &= ~GX_STATUS_MARK_NEXT;
250
4
            text_input -> gx_widget_status |= GX_STATUS_MARK_PREVIOUS;
251
        }
252
17
        else if ((click_y > client.gx_rectangle_bottom) &&
253
5
                 (text_input -> gx_multi_line_text_input_text_cursor_line < text_input -> gx_multi_line_text_view_text_total_rows))
254
        {
255
3
            if (!(text_input -> gx_widget_status & (GX_STATUS_MARK_NEXT | GX_STATUS_MARK_PREVIOUS)))
256
            {
257
                /* Start a timer to move text left. */
258
2
                _gx_system_timer_start((GX_WIDGET *)text_input, GX_MARK_TIMER,
259
                                       GX_MARK_INTERVAL, GX_MARK_INTERVAL);
260
            }
261
262
3
            text_input -> gx_widget_status &= ~GX_STATUS_MARK_PREVIOUS;
263
3
            text_input -> gx_widget_status |= GX_STATUS_MARK_NEXT;
264
        }
265
        else
266
        {
267
14
            if (text_input -> gx_widget_status & (GX_STATUS_MARK_NEXT | GX_STATUS_MARK_PREVIOUS))
268
            {
269
1
                _gx_system_timer_stop((GX_WIDGET *)text_input, GX_MARK_TIMER);
270
1
                text_input -> gx_widget_status &= ~(GX_STATUS_MARK_NEXT | GX_STATUS_MARK_PREVIOUS);
271
            }
272
        }
273
274
21
        if (scroll_shift != text_input -> gx_multi_line_text_view_text_scroll_shift)
275
        {
276
5
            _gx_system_dirty_mark((GX_WIDGET *)text_input);
277
        }
278
        else
279
        {
280
16
            if ((text_input -> gx_multi_line_text_input_start_mark != text_input -> gx_multi_line_text_input_end_mark) ||
281
4
                (text_input -> gx_multi_line_text_input_start_mark != old_end_mark))
282
            {
283
14
                _gx_multi_line_text_input_text_rectangle_get(text_input,
284
                                                             start_pos,
285
                                                             cursor_ptr -> gx_text_input_cursor_pos, &cursor_rect);
286
287
                /* Mark highlight area as dirty. */
288
14
                _gx_system_dirty_partial_add((GX_WIDGET *)text_input, &cursor_rect);
289
            }
290
        }
291
    }
292
    else
293
    {
294
2
        _gx_window_event_process((GX_WINDOW *)text_input, event_ptr);
295
    }
296
297
23
    return GX_SUCCESS;
298
}
299
300
/**************************************************************************/
301
/*                                                                        */
302
/*  FUNCTION                                               RELEASE        */
303
/*                                                                        */
304
/*    _gx_multi_line_text_input_event_process             PORTABLE C      */
305
/*                                                           6.1.3        */
306
/*  AUTHOR                                                                */
307
/*                                                                        */
308
/*    Kenneth Maxwell, Microsoft Corporation                              */
309
/*                                                                        */
310
/*  DESCRIPTION                                                           */
311
/*                                                                        */
312
/*    This function processes events for the specified text input widget. */
313
/*                                                                        */
314
/*  INPUT                                                                 */
315
/*                                                                        */
316
/*    text_input                            Multi line text input         */
317
/*                                            control block               */
318
/*    event_ptr                             Incoming event to process     */
319
/*                                                                        */
320
/*  OUTPUT                                                                */
321
/*                                                                        */
322
/*    status                                Completion status             */
323
/*                                                                        */
324
/*  CALLS                                                                 */
325
/*                                                                        */
326
/*    _gx_widget_event_process              Default widget event process  */
327
/*    _gx_system_timer_start                Allocate a free timer and     */
328
/*                                          activates it                  */
329
/*    _gx_system_timer_stop                 Stop an active GUIX timer     */
330
/*    _gx_multi_line_text_input_keydown_process                           */
331
/*                                          Process the keydown event     */
332
/*    _gx_widget_event_generate             Generate an event             */
333
/*    _gx_text_input_cursor_dirty_rectangle_get                           */
334
/*                                          Get cursor rectangle          */
335
/*    _gx_multi_line_text_input_cursor_pos_calculate                      */
336
/*                                          Calculate cursor position     */
337
/*                                            according to click positin  */
338
/*    _gx_multi_line_text_input_cursor_pos_update                         */
339
/*                                          Update cursor position        */
340
/*                                            according to insert position*/
341
/*    _gx_system_dirty_partial_add          Add a dirty area to the       */
342
/*                                            specified widget            */
343
/*    _gx_multi_line_text_view_event_process                              */
344
/*                                          Invoke the text view event    */
345
/*                                            process routine             */
346
/*                                                                        */
347
/*  CALLED BY                                                             */
348
/*                                                                        */
349
/*    Application Code                                                    */
350
/*    GUIX Internal Code                                                  */
351
/*                                                                        */
352
/*  RELEASE HISTORY                                                       */
353
/*                                                                        */
354
/*    DATE              NAME                      DESCRIPTION             */
355
/*                                                                        */
356
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
357
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
358
/*                                            resulting in version 6.1    */
359
/*  12-31-2020     Kenneth Maxwell          Modified comment(s),          */
360
/*                                            added logic to release      */
361
/*                                            dynamic input buffer,       */
362
/*                                            resulting in version 6.1.3  */
363
/*                                                                        */
364
/**************************************************************************/
365
9081
UINT  _gx_multi_line_text_input_event_process(GX_MULTI_LINE_TEXT_INPUT *text_input, GX_EVENT *event_ptr)
366
{
367
9081
GX_TEXT_INPUT_CURSOR    *cursor_ptr = &text_input -> gx_multi_line_text_input_cursor_instance;
368
9081
GX_MULTI_LINE_TEXT_VIEW *view = (GX_MULTI_LINE_TEXT_VIEW *)text_input;
369
9081
GX_WIDGET               *widget = (GX_WIDGET *)text_input;
370
9081
GX_VALUE                 blink_interval = text_input -> gx_multi_line_text_input_cursor_instance.gx_text_input_cursor_blink_interval;
371
UINT                     status;
372
GX_RECTANGLE             cursor_rect;
373
INT                      scroll_shift;
374
ULONG                    old_style;
375
376
    /* Default status to success.  */
377
9081
    status =  GX_SUCCESS;
378
379
    /* Process relative to the type of event.  */
380





9081
    switch (event_ptr -> gx_event_type)
381
    {
382
103
    case GX_EVENT_SHOW:
383
103
        _gx_window_event_process((GX_WINDOW *)text_input, event_ptr);
384
385
        /* Update cursor position. */
386
103
        _gx_multi_line_text_input_cursor_pos_update(text_input, GX_TRUE);
387
388
103
        if ((text_input -> gx_widget_style & GX_STYLE_CURSOR_ALWAYS) &&
389
5
            (text_input -> gx_widget_style & GX_STYLE_CURSOR_BLINK))
390
        {
391
            /* Start the timer.  */
392
2
            _gx_system_timer_start(widget, ID_TEXT_INPUT_TIMER, GX_CURSOR_BLINK_INTERVAL, GX_CURSOR_BLINK_INTERVAL);
393
        }
394
395
        /* Get visible rows. */
396
103
        _gx_multi_line_text_view_visible_rows_compute((GX_MULTI_LINE_TEXT_VIEW *)text_input);
397
103
        break;
398
399
109
    case GX_EVENT_STYLE_CHANGED:
400
109
        if (widget -> gx_widget_status & GX_STATUS_VISIBLE)
401
        {
402
100
            _gx_multi_line_text_view_event_process((GX_MULTI_LINE_TEXT_VIEW *)text_input, event_ptr);
403
404
100
            old_style = event_ptr -> gx_event_payload.gx_event_ulongdata;
405
100
            if ((old_style & (GX_STYLE_BORDER_MASK | GX_STYLE_TEXT_ALIGNMENT_MASK)) !=
406
100
                (widget -> gx_widget_style & (GX_STYLE_BORDER_MASK | GX_STYLE_TEXT_ALIGNMENT_MASK)))
407
            {
408
30
                text_input -> gx_multi_line_text_view_line_index_old = GX_TRUE;
409
            }
410
        }
411
109
        break;
412
413
42
    case GX_EVENT_FOCUS_GAINED:
414
        /* Call the widget default processing. */
415
42
        _gx_widget_event_process(widget, event_ptr);
416
417
        /* Do not do anything if the CURSOR_ALWAYS flag is set. */
418
42
        if (!(text_input -> gx_widget_style & GX_STYLE_CURSOR_ALWAYS))
419
        {
420
22
            text_input -> gx_widget_status |= (GX_STATUS_CURSOR_SHOW | GX_STATUS_CURSOR_DRAW);
421
422
22
            if (text_input -> gx_widget_style & GX_STYLE_CURSOR_BLINK)
423
            {
424
                /* Start the timer.  */
425
2
                _gx_system_timer_start(widget, ID_TEXT_INPUT_TIMER, (UINT)blink_interval, (UINT)blink_interval);
426
            }
427
        }
428
429
42
        _gx_multi_line_text_input_text_select(text_input, 0, text_input -> gx_multi_line_text_view_text.gx_string_length - 1);
430
42
        break;
431
432
4152
    case GX_EVENT_KEY_DOWN:
433
4152
        _gx_multi_line_text_input_keydown_process(text_input, event_ptr);
434
4152
        if (widget -> gx_widget_style & GX_STYLE_TEXT_INPUT_NOTIFY_ALL)
435
        {
436
1
            _gx_widget_event_generate(widget, GX_EVENT_TEXT_EDITED, 0);
437
        }
438
4152
        break;
439
440
1018
    case GX_EVENT_PEN_DOWN:
441
1018
        _gx_multi_line_text_input_pen_down_process(text_input, event_ptr);
442
1018
        break;
443
444
23
    case GX_EVENT_PEN_DRAG:
445
23
        _gx_multi_line_text_input_pen_drag_process(text_input, event_ptr);
446
23
        break;
447
448
130
    case GX_EVENT_PEN_UP:
449
130
        if (text_input -> gx_widget_status & GX_STATUS_OWNS_INPUT)
450
        {
451
128
            _gx_system_input_release((GX_WIDGET *)text_input);
452
453
128
            if (text_input -> gx_widget_status & (GX_STATUS_MARK_NEXT | GX_STATUS_MARK_PREVIOUS))
454
            {
455
4
                _gx_system_timer_stop((GX_WIDGET *)text_input, GX_MARK_TIMER);
456
4
                text_input -> gx_widget_status &= ~(GX_STATUS_MARK_NEXT | GX_STATUS_MARK_PREVIOUS);
457
            }
458
        }
459
        else
460
        {
461
2
            _gx_window_event_process((GX_WINDOW *)text_input, event_ptr);
462
        }
463
130
        break;
464
465
23
    case GX_EVENT_TIMER:
466
23
        if (event_ptr -> gx_event_payload.gx_event_timer_id == GX_MARK_TIMER)
467
        {
468
14
            if (text_input -> gx_widget_status & GX_STATUS_MARK_PREVIOUS)
469
            {
470
8
                _gx_multi_line_text_input_mark_up(text_input);
471
            }
472
            else
473
            {
474
6
                _gx_multi_line_text_input_mark_down(text_input);
475
            }
476
        }
477
9
        else if ((event_ptr -> gx_event_payload.gx_event_timer_id == ID_TEXT_INPUT_TIMER) &&
478
8
                 (text_input -> gx_widget_status & GX_STATUS_CURSOR_SHOW) &&
479
7
                 (text_input -> gx_multi_line_text_input_start_mark == text_input -> gx_multi_line_text_input_end_mark))
480
        {
481
6
            if (text_input -> gx_widget_status & GX_STATUS_CURSOR_DRAW)
482
            {
483
3
                text_input -> gx_widget_status &= (ULONG)(~GX_STATUS_CURSOR_DRAW);
484
            }
485
            else
486
            {
487
3
                text_input -> gx_widget_status |= GX_STATUS_CURSOR_DRAW;
488
            }
489
            /* Define a cursor rectangle for the cursor. */
490
6
            _gx_text_input_cursor_dirty_rectangle_get(&text_input -> gx_multi_line_text_input_cursor_instance, &cursor_rect);
491
6
            _gx_system_dirty_partial_add(widget, &cursor_rect);
492
        }
493
23
        break;
494
495
8
    case GX_EVENT_FOCUS_LOST:
496
8
        _gx_widget_event_process(widget, event_ptr);
497
498
        /* Do not do anything if the CURSOR_ALWAYS flag is set. */
499
8
        if (!(text_input -> gx_widget_style & GX_STYLE_CURSOR_ALWAYS))
500
        {
501
5
            text_input ->  gx_widget_status &= (ULONG)(~GX_STATUS_CURSOR_SHOW);
502
503
            /* Stop the timer if the cursor style is BLINK. */
504
5
            if (text_input -> gx_widget_style & GX_STYLE_CURSOR_BLINK)
505
            {
506
                /* Stop the timer. */
507
1
                _gx_system_timer_stop(widget, 0);
508
            }
509
510
            /* Define a cursor rectangle for the cursor. */
511
5
            _gx_text_input_cursor_dirty_rectangle_get(&text_input -> gx_multi_line_text_input_cursor_instance, &cursor_rect);
512
5
            _gx_system_dirty_partial_add(widget, &cursor_rect);
513
        }
514
515
8
        if (text_input -> gx_multi_line_text_input_start_mark != text_input -> gx_multi_line_text_input_end_mark)
516
        {
517
2
            _gx_multi_line_text_input_highlight_rectangle_get(text_input, &cursor_rect);
518
519
2
            text_input -> gx_multi_line_text_input_start_mark = 0;
520
2
            text_input -> gx_multi_line_text_input_end_mark = 0;
521
522
2
            _gx_system_dirty_partial_add(widget, &cursor_rect);
523
        }
524
525
8
        if (text_input -> gx_multi_line_text_input_text_was_modified)
526
        {
527
2
            _gx_widget_event_generate(widget, GX_EVENT_TEXT_EDITED, 0);
528
2
            text_input -> gx_multi_line_text_input_text_was_modified = GX_FALSE;
529
        }
530
8
        break;
531
532
784
    case GX_EVENT_VERTICAL_SCROLL:
533
        /* Pick up scroll shift value. */
534
784
        scroll_shift = event_ptr -> gx_event_payload.gx_event_intdata[1] - event_ptr -> gx_event_payload.gx_event_intdata[0];
535
536
        /* Move cursor position according to shift value. */
537
784
        cursor_ptr -> gx_text_input_cursor_pos.gx_point_y = (GX_VALUE)(cursor_ptr -> gx_text_input_cursor_pos.gx_point_y + scroll_shift);
538
539
        /* Call the multi-line text view event processing. */
540
784
        _gx_multi_line_text_view_event_process(view, event_ptr);
541
784
        break;
542
543
1
    case GX_EVENT_LANGUAGE_CHANGE:
544
1
        break;
545
546
3
    case GX_EVENT_COPY:
547
3
        _gx_multi_line_text_input_copy(text_input);
548
3
        break;
549
550
72
    case GX_EVENT_CUT:
551
72
        _gx_multi_line_text_input_cut(text_input);
552
72
        break;
553
554
76
    case GX_EVENT_PASTE:
555
76
        _gx_multi_line_text_input_paste(text_input);
556
76
        break;
557
558
683
    case GX_EVENT_MARK_NEXT:
559
683
        _gx_multi_line_text_input_mark_next(text_input);
560
683
        break;
561
562
661
    case GX_EVENT_MARK_PREVIOUS:
563
661
        _gx_multi_line_text_input_mark_previous(text_input);
564
661
        break;
565
566
149
    case GX_EVENT_MARK_UP:
567
149
        _gx_multi_line_text_input_mark_up(text_input);
568
149
        break;
569
570
179
    case GX_EVENT_MARK_DOWN:
571
179
        _gx_multi_line_text_input_mark_down(text_input);
572
179
        break;
573
574
63
    case GX_EVENT_MARK_END:
575
63
        _gx_multi_line_text_input_mark_end(text_input);
576
63
        break;
577
578
63
    case GX_EVENT_MARK_HOME:
579
63
        _gx_multi_line_text_input_mark_home(text_input);
580
63
        break;
581
582
3
    case GX_EVENT_DELETE:
583
3
        if (text_input -> gx_widget_status & GX_STATUS_DYNAMIC_BUFFER)
584
        {
585
2
            if (!_gx_system_memory_free)
586
            {
587
1
                return GX_SYSTEM_MEMORY_ERROR;
588
            }
589
590
1
            _gx_system_memory_free((void *)text_input -> gx_multi_line_text_view_text.gx_string_ptr);
591
1
            text_input -> gx_multi_line_text_view_text.gx_string_ptr = GX_NULL;
592
        }
593
2
        break;
594
595
736
    default:
596
        /* Call the multi-line text view event processing.  */
597
736
        status = _gx_multi_line_text_view_event_process(view, event_ptr);
598
    }
599
600
    /* Return completion status.  */
601
9080
    return(status);
602
}
603