Subversion Repositories Kolibri OS

Rev

Rev 6931 | Rev 7086 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
6198 leency 1
#ifndef INCLUDE_GUI_H
5598 pavelyakov 2
#define INCLUDE_GUI_H
3107 leency 3
 
5598 pavelyakov 4
#ifndef INCLUDE_KOLIBRI_H
5
#include "../lib/kolibri.h"
6
#endif
7
 
8
#ifndef INCLUDE_STRING_H
9
#include "../lib/strings.h"
10
#endif
11
 
6176 leency 12
#ifndef INCLUDE_RGB_H
13
#include "../lib/patterns/rgb.h"
14
#endif
15
 
4005 leency 16
:void DrawRectangle(dword x,y,w,h,color1)
3067 leency 17
{
3225 leency 18
	if (w<=0) || (h<=0) return;
19
	DrawBar(x,y,w,1,color1);
20
	DrawBar(x,y+h,w,1,color1);
21
	DrawBar(x,y,1,h,color1);
22
	DrawBar(x+w,y,1,h+1,color1);
3067 leency 23
}
24
 
5738 leency 25
:void DrawWideRectangle(dword x,y,w,h,boder,color1)
26
{
27
	if (w<=0) || (h<=0) return;
28
	DrawBar(x, y, w, boder, color1);
29
	DrawBar(x, y+h-boder, w, boder, color1);
30
	DrawBar(x, y+boder, boder, h-boder-boder, color1);
31
	DrawBar(x+w-boder, y+boder, boder, h-boder-boder, color1);
32
}
33
 
4005 leency 34
:void DrawRectangle3D(dword x,y,w,h,color1,color2)
3067 leency 35
{
3225 leency 36
	if (w<=0) || (h<=0) return;
37
	DrawBar(x,y,w+1,1,color1);
38
	DrawBar(x,y+1,1,h-1,color1);
39
	DrawBar(x+w,y+1,1,h,color2);
40
	DrawBar(x,y+h,w,1,color2);
3067 leency 41
}
42
 
4005 leency 43
:void DrawCaptButton(dword x,y,w,h,id,color_b, color_t,text)
3067 leency 44
{
6209 leency 45
	dword tx = -strlen(text)*8+w/2+x;
46
	dword ty = h/2-7+y;
47
 
4846 leency 48
	if (id>0) DefineButton(x,y,w,h,id,color_b);
6198 leency 49
	WriteText(tx+1,ty+1,0x90,MixColors(color_b,0,230),text);
50
	WriteText(tx,ty,0x90,color_t,text);
3067 leency 51
}
52
 
7031 leency 53
:int active_button_id = 0;
6631 leency 54
:int DrawStandartCaptButton(dword x, y, id, text)
6567 leency 55
{
56
	int padding_v = 5;
57
	int padding_h = 15;
58
	int right_margin = 12;
59
	int tx = x + padding_h;
6678 leency 60
	int ty = y + padding_v+1;
7031 leency 61
	int tw = strlen(text)*8;
6567 leency 62
	int h = padding_v + padding_v + 16; //16 font height
7031 leency 63
	int w = tw + padding_h + padding_h;
6567 leency 64
 
7031 leency 65
 
6631 leency 66
	if (id>0) DefineButton(x,y,w,h,id,system.color.work_button);
7031 leency 67
 
6631 leency 68
	WriteText(tx+1,ty+1,0x90,MixColors(system.color.work_button,0,230),text);
69
	WriteText(tx,ty,0x90,system.color.work_button_text,text);
7031 leency 70
 
71
	if (active_button_id==id) {
72
		DrawBar(tx,ty+15,tw,1, MixColors(system.color.work_button,0,230));
73
		DrawBar(tx,ty+14,tw,1, system.color.work_button_text);
74
	}
75
 
6567 leency 76
	return w + right_margin;
77
}
78
 
7031 leency 79
:void ActiveButtonSwitch(int min, max)
80
{
81
	active_button_id++;
82
	if (active_button_id>max) || (active_button_id
83
}
84
 
4846 leency 85
:void WriteTextCenter(dword x,y,w,color_t,text)
86
{
87
	WriteText(-strlen(text)*6+w/2+x+1,y,0x80,color_t,text);
88
}
89
 
5519 leency 90
:void DrawCircle(int x, y, r, color)
3067 leency 91
{
92
	int i;
93
	float px=0, py=r, ii = r * 3.1415926 * 2;
94
	FOR (i = 0; i < ii; i++)
95
	{
5519 leency 96
        PutPixel(px + x, y - py, color);
3067 leency 97
        px = py / r + px;
98
        py = -px / r + py;
99
	}
3076 leency 100
}
3106 leency 101
 
6271 leency 102
:unsigned char checkbox_flag[507] = {
6197 leency 103
	0xFC, 0xD4, 0x04, 0xFC, 0xD4, 0x04, 0xFC, 0xD4, 0x04, 0xFC, 0xD4, 0x04, 0xFC, 0xD4, 0x04, 0xFC,
104
	0xD4, 0x04, 0xFC, 0xD4, 0x04, 0xFC, 0xD4, 0x04, 0xFC, 0xD4, 0x04, 0xFC, 0xD4, 0x04, 0xFC, 0xD4,
105
	0x04, 0xFC, 0xD4, 0x04, 0xFC, 0xC8, 0x04, 0xFC, 0xDC, 0x04, 0xFC, 0xC8, 0x04, 0xFC, 0xC8, 0x04,
106
	0xFC, 0xC8, 0x04, 0xFC, 0xC8, 0x04, 0xFC, 0xC8, 0x04, 0xFC, 0xC8, 0x04, 0xFC, 0xC8, 0x04, 0xFC,
107
	0xC8, 0x04, 0xFC, 0xC8, 0x04, 0xFC, 0xC8, 0x04, 0xFC, 0xC8, 0x04, 0xFC, 0xB4, 0x04, 0xFC, 0xDC,
108
	0x04, 0xFC, 0xC8, 0x04, 0xFC, 0xC8, 0x04, 0xFC, 0xC8, 0x04, 0xFC, 0xC8, 0x04, 0xFC, 0xBC, 0x04,
109
	0xFC, 0xBC, 0x04, 0xFC, 0xBC, 0x04, 0xFC, 0xB4, 0x04, 0xFC, 0xA9, 0x04, 0xFC, 0xA9, 0x04, 0xFC,
110
	0xB4, 0x04, 0xFC, 0xB4, 0x04, 0xFC, 0xD4, 0x04, 0xFC, 0xC8, 0x04, 0xFC, 0xC8, 0x04, 0xFC, 0xC8,
111
	0x04, 0xFC, 0xBC, 0x04, 0xFC, 0xBC, 0x04, 0xFC, 0xB4, 0x04, 0xFC, 0xB4, 0x04, 0xF9, 0x98, 0x04,
112
	0xFC, 0xF2, 0xD2, 0xFC, 0xF2, 0xD2, 0xFA, 0xA5, 0x04, 0xFC, 0xB4, 0x04, 0xFC, 0xD4, 0x04, 0xFC,
113
	0xB4, 0x04, 0xFC, 0xA9, 0x04, 0xFC, 0xA9, 0x04, 0xFC, 0xB4, 0x04, 0xFC, 0xB4, 0x04, 0xFC, 0xB4,
114
	0x04, 0xF9, 0x98, 0x04, 0xFF, 0xFF, 0xFF, 0xFD, 0xFD, 0xF6, 0xFC, 0xF9, 0xAF, 0xF9, 0x98, 0x04,
115
	0xFC, 0xB4, 0x04, 0xFC, 0xD4, 0x04, 0xFC, 0xA9, 0x04, 0xFC, 0xF2, 0xD2, 0xFC, 0xF2, 0xD2, 0xF9,
116
	0x98, 0x04, 0xFC, 0xB4, 0x04, 0xF9, 0x98, 0x04, 0xFF, 0xFF, 0xFF, 0xFD, 0xFD, 0xF6, 0xF7, 0xE0,
117
	0x95, 0xBC, 0x64, 0x04, 0xF9, 0x98, 0x04, 0xFC, 0xA9, 0x04, 0xFC, 0xD4, 0x04, 0xF9, 0x98, 0x04,
118
	0xFD, 0xFD, 0xF6, 0xFF, 0xFF, 0xFF, 0xFC, 0xDC, 0x2C, 0xF9, 0x98, 0x04, 0xFF, 0xFF, 0xFF, 0xFD,
119
	0xFD, 0xF6, 0xF7, 0xE0, 0x95, 0xBC, 0x64, 0x04, 0xF9, 0x98, 0x04, 0xFA, 0x9F, 0x04, 0xFC, 0xA9,
120
	0x04, 0xFC, 0xD4, 0x04, 0xF9, 0x98, 0x04, 0xF7, 0xE0, 0x95, 0xFD, 0xFD, 0xF6, 0xFF, 0xFF, 0xFF,
121
	0xFF, 0xFF, 0xFF, 0xFD, 0xFD, 0xF6, 0xF7, 0xE0, 0x95, 0xBC, 0x64, 0x04, 0xF9, 0x98, 0x04, 0xFA,
122
	0x9F, 0x04, 0xFC, 0xA9, 0x04, 0xFC, 0xA9, 0x04, 0xFC, 0xD4, 0x04, 0xF9, 0x98, 0x04, 0xBC, 0x64,
123
	0x04, 0xF7, 0xE0, 0x95, 0xFD, 0xFD, 0xF6, 0xFD, 0xFD, 0xF6, 0xF7, 0xE0, 0x95, 0xBC, 0x64, 0x04,
124
	0xF9, 0x98, 0x04, 0xFA, 0x9F, 0x04, 0xFC, 0xA9, 0x04, 0xFC, 0xA9, 0x04, 0xFC, 0xA9, 0x04, 0xFC,
125
	0xC8, 0x04, 0xFA, 0xA5, 0x04, 0xF9, 0x98, 0x04, 0xBC, 0x64, 0x04, 0xF7, 0xE0, 0x95, 0xF7, 0xE0,
126
	0x95, 0xBC, 0x64, 0x04, 0xF9, 0x98, 0x04, 0xFA, 0x9F, 0x04, 0xFC, 0xA9, 0x04, 0xFC, 0xA9, 0x04,
127
	0xFC, 0xA9, 0x04, 0xFA, 0x9F, 0x04, 0xFC, 0xC8, 0x04, 0xFC, 0xA9, 0x04, 0xFA, 0x9F, 0x04, 0xF9,
128
	0x98, 0x04, 0xBC, 0x64, 0x04, 0xBC, 0x64, 0x04, 0xF9, 0x98, 0x04, 0xFA, 0x9F, 0x04, 0xFC, 0xA9,
129
	0x04, 0xFC, 0xA9, 0x04, 0xFC, 0xA9, 0x04, 0xFA, 0x9F, 0x04, 0xFA, 0x9F, 0x04, 0xFC, 0xC8, 0x04,
130
	0xFC, 0xA9, 0x04, 0xFC, 0xA9, 0x04, 0xFA, 0x9F, 0x04, 0xF9, 0x98, 0x04, 0xF9, 0x98, 0x04, 0xFA,
131
	0x9F, 0x04, 0xFC, 0xA9, 0x04, 0xFC, 0xA9, 0x04, 0xFC, 0xA9, 0x04, 0xFA, 0x9F, 0x04, 0xFA, 0x9F,
132
	0x04, 0xF9, 0x98, 0x04, 0xFC, 0xB4, 0x04, 0xF9, 0x98, 0x04, 0xF9, 0x98, 0x04, 0xF9, 0x98, 0x04,
133
	0xF9, 0x98, 0x04, 0xF9, 0x98, 0x04, 0xF9, 0x98, 0x04, 0xF9, 0x98, 0x04, 0xF9, 0x98, 0x04, 0xF9,
134
	0x98, 0x04, 0xF9, 0x98, 0x04, 0xF9, 0x98, 0x04, 0xF9, 0x98, 0x04
135
};
136
 
6176 leency 137
:void CheckBox(dword x,y,bt_id, text, is_checked)
3106 leency 138
{
6176 leency 139
	byte w=14, h=14;
6197 leency 140
	DefineButton(x-1, y-1, strlen(text)*8 + w + 17, h+2, bt_id+BT_HIDE+BT_NOFRAME, 0);
6278 leency 141
	EDI = system.color.work;
142
	WriteText(x+w+8, h / 2 + y -7, 0xD0, system.color.work_text, text);
6176 leency 143
	DrawRectangle(x, y, w, h, system.color.work_graph);
5477 leency 144
	if (is_checked == 0)
3106 leency 145
	{
5477 leency 146
		DrawRectangle3D(x+1, y+1, w-2, h-2, 0xDDDddd, 0xffffff);
147
		DrawBar(x+2, y+2, w-3, h-3, 0xffffff);
148
	}
149
	else if (is_checked == 1)
150
	{
6176 leency 151
		DrawWideRectangle(x+1, y+1, w-1, h-1, 2, 0xffffff);
6197 leency 152
		_PutImage(x+1, y+1, 13, 13, #checkbox_flag);
3106 leency 153
	}
5477 leency 154
	else if (is_checked == 2) //not active
3106 leency 155
	{
6176 leency 156
		DrawWideRectangle(x+1, y+1, w-1, h-1, 2, 0xffffff);
5526 leency 157
		DrawBar(x+3, y+3, w-5, h-5, 0x888888);
5477 leency 158
	}
6191 leency 159
	DrawRectangle3D(x-1,y-1,w+2,h+2,system.color.work_dark,system.color.work_light);
3114 leency 160
}
161
 
6176 leency 162
:void MoreLessBox(dword x,y, bt_id_more, bt_id_less, value, text)
5477 leency 163
{
6198 leency 164
	#define VALUE_FIELD_W 34
6176 leency 165
	#define SIZE 18
6198 leency 166
	dword value_text = itoa(value);
5542 leency 167
 
6931 leency 168
	DrawRectangle(x, y, VALUE_FIELD_W+1, SIZE, system.color.work_graph);
6176 leency 169
	DrawRectangle3D(x+1, y+1, VALUE_FIELD_W-2, SIZE-2, 0xDDDddd, 0xffffff);
170
	DrawBar(x+2, y+2, VALUE_FIELD_W-3, SIZE-3, 0xffffff);
6649 leency 171
	WriteText( -strlen(value_text)+3*8 + x+6, SIZE / 2 + y -6, 0x90, 0x333333, value_text);
5477 leency 172
 
6931 leency 173
	DrawCaptButton(VALUE_FIELD_W + x + 1,    y, SIZE, SIZE, bt_id_more, system.color.work_button, system.color.work_button_text, "+");
6191 leency 174
	DrawCaptButton(VALUE_FIELD_W + x + SIZE, y, SIZE, SIZE, bt_id_less, system.color.work_button, system.color.work_button_text, "-");
6278 leency 175
	EDI = system.color.work;
176
	WriteText(x+VALUE_FIELD_W+SIZE+SIZE+10, SIZE / 2 + y -7, 0xD0, system.color.work_text, text);
6191 leency 177
	DrawRectangle3D(x-1,y-1,VALUE_FIELD_W+SIZE+SIZE+2,SIZE+2,system.color.work_dark,system.color.work_light);
5477 leency 178
}
179
 
6278 leency 180
:void DrawEditBox(dword edit_box_pointer)
6193 leency 181
{
6278 leency 182
	dword x,y,w,h,bg;
6193 leency 183
	ESI = edit_box_pointer;
184
	x = ESI.edit_box.left;
185
	y = ESI.edit_box.top;
186
	w = ESI.edit_box.width+1;
6278 leency 187
	if (ESI.edit_box.flags & 100000000000b) bg = 0xCACACA; else bg = 0xFFFfff;
6678 leency 188
	edit_box_draw  stdcall (edit_box_pointer);
6708 leency 189
	h = 22;
6649 leency 190
	DrawRectangle(x-1, y-1, w+1, h+1, bg);
191
	DrawRectangle3D(x-2, y-2, w+3, h+3, 0xDDDddd, bg);
192
	DrawRectangle(x-3, y-3, w+5, h+5, system.color.work_graph);
193
	DrawRectangle3D(x-4, y-4, w+7, h+7, system.color.work_dark, system.color.work_light);
6193 leency 194
}
195
 
4686 leency 196
:void DrawProgressBar(dword st_x, st_y, st_w, st_h, col_fon, col_border, col_fill, col_text, progress_percent)
3114 leency 197
{
3225 leency 198
	int progress_w;
3114 leency 199
	static int fill_old;
200
 
3363 leency 201
	//if (progress_percent<=0) {DrawBar(st_x,st_y, st_x + st_w + fill_old + 15,st_h+1, col_fon); fill_old=0; return;}
202
	if (progress_percent<=0) || (progress_percent>=100) return;
3114 leency 203
 
204
	DrawRectangle(st_x, st_y, st_w,st_h, col_border);
205
	DrawRectangle3D(st_x+1, st_y+1, st_w-2,st_h-2, 0xFFFfff, 0xFFFfff);
3225 leency 206
 
207
	if (progress_percent>0) && (progress_percent<=100)
208
	{
209
		progress_w = st_w - 3 * progress_percent / 100;
210
		DrawBar(st_x+2, st_y+2, progress_w, st_h-3, col_fill);
211
		DrawBar(st_x+2+progress_w, st_y+2, st_w-progress_w-3, st_h-3, 0xFFFfff);
212
	}
3363 leency 213
}
214
 
215
:void DrawLink(dword x,y,font_type,btn_id, inscription)
216
{
217
	int w;
218
	WriteText(x,y,font_type,0x4E00E7,inscription);
7031 leency 219
	if (font_type==0x80) w = strlen(inscription)*6; else w = strlen(inscription)*8;
3363 leency 220
	DefineButton(x-1,y-1,w,10,btn_id+BT_HIDE,0);
221
	DrawBar(x,y+8,w,1,0x4E00E7);
222
}
223
 
3991 leency 224
:void PutShadow(dword x,y,w,h,skinned,strength)
3363 leency 225
{
226
	proc_info wForm;
227
	dword shadow_buf, skin_height;
228
	shadow_buf = mem_Alloc(w*h*3);
229
 	GetProcessInfo(#wForm, SelfInfo);
3991 leency 230
	CopyScreen(shadow_buf, 5*skinned+x+wForm.left, GetSkinHeight()*skinned+y+wForm.top, w, h);
3363 leency 231
	ShadowImage(shadow_buf, w, h, strength);
232
	_PutImage(x,y,w,h,shadow_buf);
233
	mem_Free(shadow_buf);
234
}
235
 
3991 leency 236
:void DrawPopup(dword x,y,w,h,skinned, col_work,col_border)
237
{
238
	DrawRectangle(x,y,w,h,col_border);
3992 leency 239
	DrawBar(x+1,y+1,w-1,1,0xFFFfff);
4029 leency 240
	DrawBar(x+1,y+2,1,h-2,0xFFFfff);
3992 leency 241
	if (col_work!=-1) DrawBar(x+2,y+2,w-2,h-2,col_work);
3991 leency 242
	DrawPopupShadow(x,y,w,h-1,skinned);
243
}
244
 
5499 leency 245
:void DrawPopupShadow(dword x,y,w,h,skinned)
246
{
247
	PutShadow(w+x+1,y,1,h+2,skinned,2);
248
	PutShadow(w+x+2,y+1,1,h+2,skinned,1);
249
	PutShadow(x,y+h+2,w+2,1,skinned,2);
250
	PutShadow(x+1,y+h+3,w+1,1,skinned,1);
251
}
252
 
3363 leency 253
:void GrayScaleImage(dword color_image, w, h)
254
{
5761 leency 255
	dword i,gray,to,rr,gg,bb;
256
	to = w*h*3 + color_image;
257
	for (i = color_image; i < to; i+=3)
3363 leency 258
	{
5761 leency 259
		rr = DSBYTE[i];
260
		gg = DSBYTE[i+1];
261
		bb = DSBYTE[i+2];
3363 leency 262
		gray = rr*rr;
263
		gray += gg*gg;
264
		gray += bb*bb;
265
		gray = sqrt(gray) / 3;
5761 leency 266
		DSBYTE[i] = DSBYTE[i+1] = DSBYTE[i+2] = gray;
3363 leency 267
	}
268
}
269
 
270
:void ShadowImage(dword color_image, w, h, strength)
271
{
272
	dword col, to;
273
	strength = 10 - strength;
274
	to = w*h*3 + color_image;
275
	for ( ; color_image < to; color_image++)
276
	{
277
		col = strength * DSBYTE[color_image] / 10;
278
		DSBYTE[color_image] = col;
279
	}
5598 pavelyakov 280
}
281
 
5962 leency 282
:void WriteTextLines(dword x,y,byte fontType, dword color, text_pointer, line_h)
283
{
284
	dword next_word_pointer = strchr(text_pointer, '\n');
285
	if (next_word_pointer) WriteTextLines(dword x, y+line_h, byte fontType, dword color, next_word_pointer+2, line_h);
286
	ESBYTE[next_word_pointer] = NULL;
287
	WriteText(dword x, y, byte fontType, dword color, text_pointer);
288
	ESBYTE[next_word_pointer] = '\n';
289
}
290
 
6631 leency 291
/*
292
We have a long text and need to show it in block.
293
Normal line break '\n' must be applied.
294
Long lines should be breaked by word.
295
TODO: scroll
296
*/
6651 leency 297
:int DrawTextViewArea(int x,y,w,h, dword buf_start, bg_col, text_col)
6631 leency 298
{
299
	dword write_start;
300
	dword buf_end;
6651 leency 301
	int line_h = 15;
6631 leency 302
	int label_length_max;
303
	int write_length;
304
	bool end_found;
305
 
306
	write_start = buf_start;
307
	buf_end = strlen(buf_start) + buf_start;
308
	label_length_max  = w / 8; // 8 big font char width
309
 
310
	loop()
311
	{
312
		if (bg_col!=-1) DrawBar(x, y, w+1, line_h, bg_col);
313
		end_found = false;
314
		write_length = strchr(write_start, '\n') - write_start; //search normal line break
315
		if (write_length > label_length_max) || (write_length<=0) //check its position: exceeds maximum line length or not found
316
		{
317
			if (buf_end - write_start < label_length_max) //check does current line the last
318
			{
319
				write_length = buf_end - write_start;
320
				end_found = true;
321
			}
322
			else
323
			{
324
				for (write_length=label_length_max; write_length>0; write_length--) { //search for white space to make the line break
325
					if (ESBYTE[write_start+write_length] == ' ') {
326
						end_found = true;
327
						break;
328
					}
329
				}
330
			}
331
			if (end_found != true) write_length = label_length_max; //no white space, so we write label_length_max
332
		}
333
		ESI = write_length; //set text length attribute for WriteText()
6662 leency 334
		WriteText(x, y, 0x10, text_col, write_start);
6631 leency 335
		// if (editpos >= write_start-buf_start) && (editpos <= write_start-buf_start + write_length) {
336
		// 	WriteTextB(-write_start+buf_start+editpos * 8 + x - 5 +1, y, 0x90, 0xFF0000, "|");
337
		// }
338
		write_start += write_length + 1;
339
		y += line_h;
340
		if (write_start >= buf_end) break;
341
	}
342
	if (bg_col!=-1) DrawBar(x,y,w+1,h-y+line_h-4,bg_col);
343
	return y+line_h;
344
}
345
 
346
 
6197 leency 347
//this function increase falue and return it
348
//useful for list of controls which goes one after one
349
struct incn
350
{
351
	dword n;
352
	dword inc(dword _addition);
353
};
354
 
355
dword incn::inc(dword _addition)
356
{
357
	n+=_addition;
358
	return n;
359
}
360
 
6264 leency 361
 
362
/*=========================================================
363
==
364
==                   TABS
365
==
366
/========================================================*/
367
 
368
#define TAB_PADDING 25
369
#define TAB_HEIGHT 25
370
 
6271 leency 371
:struct _tabs
6264 leency 372
{
373
	int active_tab;
374
	void draw();
375
	int click();
376
} tabs;
377
 
6271 leency 378
:void _tabs::draw(dword x,y, but_id, text)
6264 leency 379
{
380
	dword col_bg, col_text;
381
	dword w=strlen(text)*8+TAB_PADDING, h=TAB_HEIGHT;
382
	y -= h;
383
 
384
	if (but_id==active_tab)
385
	{
386
		col_bg=system.color.work_button;
387
		col_text=system.color.work_button_text;
388
	}
389
	else
390
	{
391
		col_bg=system.color.work;
392
		col_text=system.color.work_text;
393
	}
394
	DrawCaptButton(x,y, w-1,h+1, but_id, col_bg, col_text, text);
395
}
396
 
6271 leency 397
:int _tabs::click(int N)
6264 leency 398
{
399
	if (N==active_tab) return false;
400
	active_tab = N;
401
	return true;
402
}
403
 
404
 
405
 
5598 pavelyakov 406
#endif