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 /**   Widget Management (Widget)                                          */
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_widget.h"
29 
30 
31 /**************************************************************************/
32 /*                                                                        */
33 /*  FUNCTION                                               RELEASE        */
34 /*                                                                        */
35 /*    _gx_widget_child_focus_assign                       PORTABLE C      */
36 /*                                                           6.1          */
37 /*  AUTHOR                                                                */
38 /*                                                                        */
39 /*    Kenneth Maxwell, Microsoft Corporation                              */
40 /*                                                                        */
41 /*  DESCRIPTION                                                           */
42 /*                                                                        */
43 /*    This function processes events for the specified widget.            */
44 /*                                                                        */
45 /*  INPUT                                                                 */
46 /*                                                                        */
47 /*    widget                                Widget control block          */
48 /*                                                                        */
49 /*  OUTPUT                                                                */
50 /*                                                                        */
51 /*    status                                Completion status             */
52 /*                                                                        */
53 /*  CALLS                                                                 */
54 /*                                                                        */
55 /*    gx_system_focus_claim()                                             */
56 /*                                                                        */
57 /*  CALLED BY                                                             */
58 /*                                                                        */
59 /*    Application Code                                                    */
60 /*    GUIX Internal Code                                                  */
61 /*                                                                        */
62 /*  RELEASE HISTORY                                                       */
63 /*                                                                        */
64 /*    DATE              NAME                      DESCRIPTION             */
65 /*                                                                        */
66 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
67 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
68 /*                                            resulting in version 6.1    */
69 /*                                                                        */
70 /**************************************************************************/
_gx_widget_child_focus_assign(GX_WIDGET * parent)71 VOID _gx_widget_child_focus_assign(GX_WIDGET *parent)
72 {
73 GX_WIDGET *winner = GX_NULL;
74 GX_WIDGET *test = parent -> gx_widget_first_child;
75 
76     /* does any child have default focus status? */
77     while (test)
78     {
79         if (test -> gx_widget_status & GX_STATUS_DEFAULT_FOCUS)
80         {
81             winner = test;
82 
83             if (winner -> gx_widget_status & GX_STATUS_NAV_PARENT)
84             {
85                 break;
86             }
87             else
88             {
89                 /* keep drilling down to children of children */
90                 test = winner -> gx_widget_first_child;
91             }
92         }
93         else
94         {
95             test = test -> gx_widget_next;
96         }
97     }
98 
99     if (winner)
100     {
101         if (!(winner -> gx_widget_status & GX_STATUS_HAS_FOCUS) ||
102             winner != _gx_system_focus_owner)
103         {
104             _gx_system_focus_claim(winner);
105         }
106         return;
107     }
108 
109     /* nothing has default focus flag, so just try to give focus to first child that accepts focus */
110     test = parent -> gx_widget_first_child;
111 
112     while (test)
113     {
114         if ((test -> gx_widget_status & GX_STATUS_ACCEPTS_FOCUS) &&
115             !(test -> gx_widget_status & GX_STATUS_NONCLIENT))
116         {
117             winner = test;
118 
119             if (winner -> gx_widget_status & GX_STATUS_NAV_PARENT)
120             {
121                 break;
122             }
123             else
124             {
125                 test = winner -> gx_widget_first_child;
126             }
127         }
128         else
129         {
130             test = test -> gx_widget_next;
131         }
132     }
133 
134     if (winner && !(winner -> gx_widget_status & GX_STATUS_HAS_FOCUS))
135     {
136         _gx_system_focus_claim(winner);
137     }
138 }
139 
140