aboutsummaryrefslogtreecommitdiffstats
path: root/Lessons/Lesson_58/README.md
blob: 710a1d16736a46a23aba74456a8638e2d22cc95d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
Let's start to investigate form elements.

Create new app `HIIStaticForm` with a content similar to our `HIISimpleForm` app. I won't repeat all the steps, as in this lesson we would only change form content.

So we start with this VFR:
```
#define HIISTATICFORM_FORMSET_GUID  {0x32783cc5, 0xe551, 0x4b61, {0xb7, 0xbd, 0x41, 0xba, 0x71, 0x7f, 0xba, 0x81}}

formset
  guid     = HIISTATICFORM_FORMSET_GUID,
  title    = STRING_TOKEN(HIISTATICFORM_FORMSET_TITLE),
  help     = STRING_TOKEN(HIISTATICFORM_FORMSET_HELP),
  form
    formid = 1,
    title = STRING_TOKEN(HIISTATICFORM_FORMID1_TITLE);
  endform;
endformset;
```
And it produces the folowing code:
```
formset
>00000000: 0E A7 C5 3C 78 32 51 E5 61 4B B7 BD 41 BA 71 7F BA 81 02 00 03 00 01 71 99 03 93 45 85 04 4B B4 5E 32 EB 83 26 04 0E
>00000027: 5C 06 00 00 00 00
>0000002D: 5C 06 00 00 01 00
  guid = {0x32783cc5, 0xe551, 0x4b61, {0xb7, 0xbd, 0x41, 0xba, 0x71, 0x7f, 0xba, 0x81}},
  title = STRING_TOKEN(0x0002),
  help = STRING_TOKEN(0x0003),
  form
>00000033: 01 86 01 00 04 00
    formid = 1,
    title = STRING_TOKEN(0x0004);
  endform;
>00000039: 29 02
endformset;
>0000003B: 29 02
```
And as you remember this creates an empty form with a title.

# Subtitle

The most simple form element is subtitle (https://edk2-docs.gitbook.io/edk-ii-vfr-specification/2_vfr_description_in_bnf/211_vfr_form_definition#2.11.5.1-vfr-subtitle-definition). It is a non-interactive text to display some information to the user. Is is not possible to select this element. In EDKII form browser it is also displayed in a blue color (opposed to the interactive elements, that would be displayed in black color).

You can add subtitle with this code:
```
subtitle
  text = STRING_TOKEN(SUBTITLE1),
endsubtitle;
```
But it is most common to use a short form:
```
subtitle text = STRING_TOKEN(SUBTITLE1);
```

Simply embed this string inside our form code:
```
...
form
  formid = 1,
  title = STRING_TOKEN(HIISTATICFORM_FORMID1_TITLE);

  subtitle text = STRING_TOKEN(SUBTITLE1);
endform;
...
```

Off course you should declare this string in the UNI file:
```
#string SUBTITLE1                            #language en-US  "Subtitle1"
```

This VFR would produce following picture:

![Subtitle1](Subtitle1.png?raw=true "Subtitle1")

# IFR

```
formset
>00000000: 0E A7 C5 3C 78 32 51 E5 61 4B B7 BD 41 BA 71 7F BA 81 02 00 03 00 01 71 99 03 93 45 85 04 4B B4 5E 32 EB 83 26 04 0E
>00000027: 5C 06 00 00 00 00
>0000002D: 5C 06 00 00 01 00
  guid = {0x32783cc5, 0xe551, 0x4b61, {0xb7, 0xbd, 0x41, 0xba, 0x71, 0x7f, 0xba, 0x81}},
  title = STRING_TOKEN(0x0002),
  help = STRING_TOKEN(0x0003),
  form
>00000033: 01 86 01 00 04 00
    formid = 1,
    title = STRING_TOKEN(0x0004);
    subtitle text = STRING_TOKEN(0x0005);
>00000039: 02 87 05 00 00 00 00
>00000040: 29 02
  endform;
>00000042: 29 02
endformset;
>00000044: 29 02
```

If you compare output before and after you could see that the difference is:
```
    subtitle text = STRING_TOKEN(0x0005);
>00000039: 02 87 05 00 00 00 00
>00000040: 29 02
```

It is two opcodes: `EFI_IFR_SUBTITLE` and our `EFI_IFR_END`. We've already seen the structure for the `EFI_IFR_END`, so let's look at the `EFI_IFR_SUBTITLE`:
```
EFI_IFR_SUBTITLE

Summary:
Creates a sub-title in the current form.

Prototype:

#define EFI_IFR_SUBTITLE_OP 0x02

typedef struct _EFI_IFR_SUBTITLE {
 EFI_IFR_OP_HEADER Header;
 EFI_IFR_STATEMENT_HEADER Statement;
 UINT8 Flags;
} EFI_IFR_SUBTITLE;

Members:
Header 		The sequence that defines the type of opcode as well as the length of the opcode being defined.
		For this tag, Header.OpCode = EFI_IFR_SUBTITLE_OP.
Flags 		Identifies specific behavior for the sub-title.
```


# Another subtitle

If you add another subtitle similar to like we did it above:
```
...
form
  formid = 1,
  title = STRING_TOKEN(HIISTATICFORM_FORMID1_TITLE);

  subtitle text = STRING_TOKEN(SUBTITLE1);
  subtitle text = STRING_TOKEN(SUBTITLE2);
endform;
...
```

This subtitle will be simply printed on the next string. This principle is true for all form elements. Next element by default will simply go to another string.

![Subtitle2](Subtitle2.png?raw=true "Subtitle2")

# Utilizing subtitle scope

As we saw above, `EFI_IFR_SUBTITLE` opens a scope which is later closed by the `EFI_IFR_END`.

It is possible to define elements inside subtitle scope which will indent all the elements inside the scope.

Add this construction to our form:
```
subtitle
  text = STRING_TOKEN(SUBTITLE3),

  subtitle text = STRING_TOKEN(SUBTITLE4);
endsubtitle;
```

If you look at the `Form.lst` you would see that 
```
    subtitle
>0000004B: 02 87 07 00 00 00 00
      text = STRING_TOKEN(0x0007),
      subtitle text = STRING_TOKEN(0x0008);
>00000052: 02 87 08 00 00 00 00
>00000059: 29 02
    endsubtitle;
>0000005B: 29 02
```
Here you can see opcodes `EFI_IFR_SUBTITLE`-`EFI_IFR_SUBTITLE`-`EFI_IFR_END`-`EFI_IFR_END`. If we didn't put `SUBTITLE4` in the `SUBTITLE3` scope, the output would be `EFI_IFR_SUBTITLE`-`EFI_IFR_END`-`EFI_IFR_SUBTITLE`-`EFI_IFR_END`.


![Subtitle3](Subtitle3.png?raw=true "Subtitle3")

To get more deeper understanding add another subtitle inside the scope of `SUBTITLE3` and another after the scope:
```
subtitle
  text = STRING_TOKEN(SUBTITLE3),

  subtitle text = STRING_TOKEN(SUBTITLE4);
  subtitle text = STRING_TOKEN(SUBTITLE5);
endsubtitle;

subtitle text = STRING_TOKEN(SUBTITLE6);
```

![Subtitle4](Subtitle4.png?raw=true "Subtitle4")

# Empty string

Subtitle element is an easy way to add an empty string to your form.

Insert this code right before the `SUBTITLE6` definition
```
subtitle text = STRING_TOKEN(STR_NULL);
```
And define `STR_NULL` as:
```
#string STR_NULL                             #language en-US  ""
```

This would give you:

![Subtitle5](Subtitle5.png?raw=true "Subtitle5")

# Text element

The next element that we will discuss is `text` (https://edk2-docs.gitbook.io/edk-ii-vfr-specification/2_vfr_description_in_bnf/211_vfr_form_definition#2.11.5.2-vfr-text-definition). Add following code to our form right after the last subtitle:
```
text
  help = STRING_TOKEN(TEXT1_help),
  text = STRING_TOKEN(TEXT1_text);
```

If you would look at the `Form.lst`, you'll see that `text` doesn't open a scope, therefore only one IFR is produced - `EFI_IFR_TEXT`:
```
    text
>00000078: 03 08 0C 00 0D 00 00 00
      help = STRING_TOKEN(0x000D),
      text = STRING_TOKEN(0x000C);
```

```
EFI_IFR_TEXT

Summary:
Creates a static text and image.

Prototype:

#define EFI_IFR_TEXT_OP 0x03

typedef struct _EFI_IFR_TEXT {
 EFI_IFR_OP_HEADER Header;
 EFI_IFR_STATEMENT_HEADER Statement;
 EFI_STRING_ID TextTwo;
} EFI_IFR_TEXT;

Members:
Header 		The sequence that defines the type of opcode as well as the length of the opcode being defined.
		For this tag, Header.OpCode = EFI_IFR_TEXT_OP.
Statement 	Standard statement header.
TextTwo 	The string token reference to the secondary string for this opcode.

Description:
This is a static text/image statement.
```
And here is a definition for the `EFI_IFR_STATEMENT_HEADER` field:
```
EFI_IFR_STATEMENT_HEADER

Summary:
Standard statement header.

Prototype:
typedef struct _EFI_IFR_STATEMENT_HEADER {
 EFI_STRING_ID Prompt;
 EFI_STRING_ID Help;
} EFI_IFR_STATEMENT_HEADER;

Members:
Prompt 	The string identifier of the prompt string for this particular statement. The value 0 indicates no prompt string.
Help 	The string identifier of the help string for this particular statement. The value 0 indicates no help string

Description:
This is the standard header for statements, including questions.
```

On the screen `text` element looks like this:

![Text1](Text1.png?raw=true "Text1")

The main difference of the `text` element from the `subtitle` element is that you can select `text` elements.

This is more obvious if you'll add another text element right after the first one:

![Text2](Text2.png?raw=true "Text2")

Now you can use arrow keys to select either `Text1 title` or `Text2 title`. And when you would do this help text for title would change automatically.

# Another text field

It is possible to add another text field to the text element:
```
text
  help = STRING_TOKEN(TEXT3_HELP),
  text = STRING_TOKEN(TEXT3_TEXT);
  text = STRING_TOKEN(TEXT3_TEXT_TWO);
```
Its string would go to the `EFI_IFR_TEXT.TextTwo` field.

In the browser it would like this. The second string is placed in a choice place for the menu item:

![Text3](Text3.png?raw=true "Text3")