Subversion Repositories Kolibri OS

Rev

Rev 8184 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
8133 IgorA 1
#ifndef __KOLIBRI_H_INCLUDED_
2
#define __KOLIBRI_H_INCLUDED_
8129 IgorA 3
 
8184 IgorA 4
#include "kos_lib.h"
8129 IgorA 5
 
6
// Kolibri interface.
7
 
8
namespace Kolibri   // All kolibri functions, types and data are nested in the (Kolibri) namespace.
9
{
10
	const char *DebugPrefix = "User program: ";
8252 IgorA 11
	char CommandLine[2048];
8129 IgorA 12
 
13
	struct TWindowData   // Data for drawing a window.
14
	{
15
		unsigned short WindowType, HeaderType;
16
		unsigned long WindowColor, HeaderColor, BorderColor, TitleColor;
17
		const char *Title;
18
	};
19
 
8133 IgorA 20
	struct TStartData   // This structure is used only for KolibriOnStart function.
8129 IgorA 21
	{
22
		unsigned short Left, Width, Top, Height; // Initial window rectangle.
23
		TWindowData WinData;
24
	};
25
 
26
	typedef void **TThreadData;   // Thread data are the fast identifier of thread, contains user dword in
27
			//_ the zero element and stack beginning (or zero if it is unknown) in the first element.
28
			//_ The stack will be deleted from dynamic memory at the finish of the thread if stack beginning is not zero.
29
 
30
	struct TMutex;   // Simple mutex can be locked only once at a time.
8170 IgorA 31
#define KOLIBRI_MUTEX_INIT {}   // Simple mutex initializer, cat be redefined in a realization of the library
8129 IgorA 32
 
33
	struct TRecMutex;   // Recursive mutex can be locked many times by a single thread at a time.
8170 IgorA 34
#define KOLIBRI_REC_MUTEX_INIT {}   // Recursive mutex initializer, cat be redefined in a realization of the library
8129 IgorA 35
 
36
	// Some functions have two forms: the fast form with (thread_data) parameter and the form without it.
37
	// Note: pass only thread data of current thread as (thread_data) parameter to these functions.
38
 
39
	void Main();   // Main function is called at program startup.
8184 IgorA 40
	void DrawButton(long id, long color, long x, long y, long c_x, long c_y);   // Draw Standard button
8129 IgorA 41
	void* ThreadMain(void *user = 0, void *stack_begin = 0);
42
			// Called at thread startup, (user) is placed in thread data as a user dword,
43
			//_ (stack_begin) is placed in thread data as a stack beginning.
44
			//_ Return new value of stack beginning that can be changed in the thread data.
45
	void GetWindowData(TWindowData &win_data);   // Write current window data to (win_data).
46
	void GetWindowData(TWindowData &win_data, TThreadData thread_data);
47
	void SetWindowData(const TWindowData &win_data);   // Replace current window data by (win_data).
48
	void SetWindowData(const TWindowData &win_data, TThreadData thread_data);
49
	void CloseWindow();   // Close current window when returning to message loop.
50
	void CloseWindow(TThreadData thread_data);
51
	void Redraw(int frame = 0);   // Redraw current window immediately, if (frame) is positive redraw the frame too,
52
	void Redraw(int frame, TThreadData thread_data);   //_ if (frame) is negative redraw only invalideted window.
53
	void Invalidate(int frame = 0);   // Redraw current window when no message will be is the queue,
54
	void Invalidate(int frame, TThreadData thread_data);   //_ if (frame) is positive redraw the frame too,
55
														   //_ if (frame) is negative do nothing.
56
	void MoveWindow(const int window_rect[/* 4 */]);   // Move and resize current window.
57
 
8184 IgorA 58
	void ExitDebug();    // Abnormally terminate a program.
59
	void ExitProcess();  // Exit from the process, don't call any destructors of global varyables
8129 IgorA 60
	void ExitThread();   // Exit from the current thread
61
	void ExitThread(TThreadData thread_data);
62
	void ReturnMessageLoop();   // Return to the message loop of the thread. Exit from the thread
8133 IgorA 63
	void ReturnMessageLoop(TThreadData thread_data);   //_ if it is called from (KolibriOnStart).
8129 IgorA 64
 
65
	void Delay(unsigned int time);   // Delay the execution of the program during (time) hundredth seconds.
66
	unsigned int Clock();   // Return the time from starting of the system to this moment in hundredth of seconds.
67
	int GetPackedTime();   // Return the current time of day in binary-decimal format 0x00SSMMHH.
68
	void GetTime(int t[/* 3 */]);   // Write the current time to (t): t[0] = second, t[1] = minute, t[2] = hour.
69
	int GetPackedDate();   // Return the current date in binary-decimal format 0x00YYDDMM.
70
	void GetDate(int d[/* 3 */]);   // Write the current date to (d): d[0] = day, d[1] = month, d[2] = year.
71
	void GetTimeDate(int t[/* 6 */]);   // Write the current time and date to (t): t[0] = second,
72
										//_ t[1] = minute, t[2] = hour, t[3] = day, t[4] = month, t[5] = year.
73
	void ReadCommonColors(unsigned int colors[/* 10 */]);   // Writes standart window colors to (colors).
74
	unsigned int GetProcessInfo(unsigned int *use_cpu, char process_name[/* 13 */], unsigned int *use_memory,
75
								unsigned int *pid, int window_rect[/* 4 */], unsigned int pid_for = -1);
76
								// Write (pid_for) process information to variables parameters points, return
77
								//_ the number of processes. (pid_for) equal to (-1) means current process.
78
	unsigned int GetPid();   // Return the current thread identifier (pid).
79
	unsigned int GetPid(TThreadData thread_data);
80
	TThreadData GetThreadData();   // Return the thread data of the current thread.
81
	TThreadData GetThreadData(unsigned int pid);   // Return the thread data of the thread with the given pid.
82
 
83
	void* GetPicture(unsigned short &width, unsigned short &height);
84
	void* GetPicture(unsigned short &width, unsigned short &height, TThreadData thread_data);
85
			// Return the picture on the window and write its width and height to (width) and (height).
86
	void SetPicture(void *picture, unsigned short width, unsigned short height);
87
	void SetPicture(void *picture, unsigned short width, unsigned short height, TThreadData thread_data);
88
			// Replace the picture on the window by the given picture with the given width and height.
89
	void GetBorderHeader(unsigned short &border_size, unsigned short &header_size);
90
	void GetBorderHeader(unsigned short &border_size, unsigned short &header_size, TThreadData thread_data);
91
			// Write the border thickness to (border_size) and header height to (header_size).
92
	void GetClientSize(unsigned short &width, unsigned short &height);
93
	void GetClientSize(unsigned short &width, unsigned short &height, TThreadData thread_data);
94
			// Write the client area width and height to (width) and (height) parameters.
95
	void GetClientSize(unsigned short &width, unsigned short &height, int win_width, int win_height);
96
	void GetClientSize(unsigned short &width, unsigned short &height, int win_width, int win_height, TThreadData thread_data);
97
			// Write the client area size of window with the width (win_width)
98
			//_ and height (win_height) to (width) and (height) parameters.
99
	void GetScreenSize(unsigned short &width, unsigned short &height);
100
			// Write the screen width and height to (width) and (height) parameters.
101
 
102
	void InitMutex(TMutex *mutex);   // Initialize the simple mutex.
103
	void InitRecMutex(TRecMutex *mutex);   // Initialize the recursive mutex.
104
	bool TryLock(TMutex *mutex);   // Try to lock the mutex without waitting, return true if lock.
105
	bool TryLock(TRecMutex *mutex);
106
	bool TryLock(TRecMutex *mutex, TThreadData thread_data);
107
	bool TryLock(TRecMutex *mutex, unsigned int pid);
108
	void Lock(TMutex *mutex);   // Lock mutex and wait for it if this necessary.
109
	void Lock(TRecMutex *mutex);
110
	void Lock(TRecMutex *mutex, TThreadData thread_data);
111
	void Lock(TRecMutex *mutex, unsigned int pid);
112
	bool LockTime(TMutex *mutex, int time);
113
	bool LockTime(TRecMutex *mutex, int time);   // Lock mutex and wait for it during (time) hundredth seconds.
114
	bool LockTime(TRecMutex *mutex, int time, TThreadData thread_data);
115
	bool LockTime(TRecMutex *mutex, int time, unsigned int pid);
116
	void UnLock(TMutex *mutex);   // Unlock mutex
117
	void UnLock(TRecMutex *mutex);
118
	void UnLock(TRecMutex *mutex, TThreadData thread_data);
119
	void UnLock(TRecMutex *mutex, unsigned int pid);
120
 
121
	void DebugPutChar(char c);   // Put the character to the debug board.
122
	void DebugPutString(const char *s);   // Put the string to the debug board.
123
	int GetKey();   // Return key pressed by user or -1 if no key was pressed.
124
	int GetMouseButton();   // Return buttons pressed: 0 - no buttons, 1 - left button, 2 - right button, 3 - both buttons.
125
	void GetMousePosition(short &x, short &y, bool absolute = false);
126
			// Write mouse position to (x) and (y): absolute if (absolute) is true and relative the window otherwise.
127
	void GetMousePosPicture(short &x, short &y);
128
 
129
	int GetThreadNumber();   // Return the number of threads currently executing.
130
	bool WasThreadCreated();   // Return true if there was created at least one thread except the main thred.
131
	unsigned int CreateThread(void *user = 0, unsigned int stack_size = 0, void *stack_end = 0);
132
			// Create a new thread with the user dword (user) and stack pointer (stack_end).
133
			//_ If (stack_end) is zero, create stack in dynamic memory of size (stack_size) or
134
			//_ the same size as the main thread if (stack_size) less that 4096. Set the beginning
135
			//_ of the stack if (stack_end) is zero or (stack_size) is not zero, in this case stack
136
			//_ will be deleted automaticaly from dynamic memory at the finish of the thread.
8133 IgorA 137
	void DrawText(short x, short y, int color, const char* string);
8184 IgorA 138
	void SetWindowCaption(const char* caption);
8129 IgorA 139
}
140
 
141
// Function, defined outside.
142
 
8133 IgorA 143
bool KolibriOnStart(Kolibri::TStartData &me_start, Kolibri::TThreadData thread_data);
8129 IgorA 144
			// Window will be created iff return value is true.
8133 IgorA 145
bool KolibriOnClose(Kolibri::TThreadData thread_data);     // Window will be closed iff return value is true.
146
int KolibriOnIdle(Kolibri::TThreadData thread_data);       // Return the time to wait next message.
147
void KolibriOnSize(int window_rect[/* 4 */], Kolibri::TThreadData thread_data);  // When the window is resized.
148
void KolibriOnKeyPress(Kolibri::TThreadData thread_data);  // When user press a key.
149
void KolibriOnMouse(Kolibri::TThreadData thread_data);     // When user move a mouse.
8184 IgorA 150
void KolibriOnButton(long id, Kolibri::TThreadData th);
8129 IgorA 151
 
8170 IgorA 152
#ifdef __KOLIBRI__
8129 IgorA 153
 
154
namespace Kolibri
155
{
156
// Structures.
157
 
158
	struct TMutex   // Simple mutex can be locked only once at a time.
159
	{
160
		unsigned int mut;
161
	};
8170 IgorA 162
#undef  KOLIBRI_MUTEX_INIT
163
#define KOLIBRI_MUTEX_INIT {0x40}   // Simple mutex initializer, cat be redefined in a realization of the library
8129 IgorA 164
 
165
	struct TRecMutex   // Recursive mutex can be locked many times by a single thread at a time.
166
	{
167
		unsigned int mut, pid;
168
	};
8170 IgorA 169
#undef  KOLIBRI_REC_MUTEX_INIT
170
#define KOLIBRI_REC_MUTEX_INIT {0x20,-1}   // Recursive mutex initializer, cat be redefined in a realization of the library
8129 IgorA 171
 
172
// Global variables.
173
 
174
	volatile TThreadData _ThreadTable[256];
175
	volatile unsigned int _ThreadScanCount[2] = {0, 0};
176
	volatile int _ThreadNumber = 1;
177
	volatile int _ExitProcessNow = 0;
8170 IgorA 178
	TMutex _ThreadMutex = KOLIBRI_MUTEX_INIT;
8129 IgorA 179
	unsigned int _ThreadSavedBegProc[4];
180
 
181
// Inline functions.
182
 
183
	inline void GetWindowData(TWindowData &win_data) {GetWindowData(win_data, GetThreadData());}
184
 
185
	inline void SetWindowData(const TWindowData &win_data) {SetWindowData(win_data, GetThreadData());}
186
 
187
	inline void CloseWindow() {CloseWindow(GetThreadData());}
188
 
189
	inline void Redraw(int frame) {Redraw(frame, GetThreadData());}
190
 
191
	inline void Invalidate(int frame) {Invalidate(frame, GetThreadData());}
192
 
193
	inline void* GetPicture(unsigned short &width, unsigned short &height)
194
	{
195
		return GetPicture(width, height, GetThreadData());
196
	}
197
 
198
	inline void SetPicture(void *picture, unsigned short width, unsigned short height)
199
	{
200
		SetPicture(picture, width, height, GetThreadData());
201
	}
202
 
203
	inline void GetBorderHeader(unsigned short &border_size, unsigned short &header_size)
204
	{
205
		GetBorderHeader(border_size, header_size, GetThreadData());
206
	}
207
 
208
	inline void GetClientSize(unsigned short &width, unsigned short &height)
209
	{
210
		unsigned int pid;
211
		int rect[4];
212
		GetProcessInfo(0, 0, 0, &pid, rect);
213
		GetClientSize(width, height, rect[2], rect[3], GetThreadData(pid));
214
	}
215
 
216
	inline void GetClientSize(unsigned short &width, unsigned short &height, TThreadData thread_data)
217
	{
218
		int rect[4];
219
		GetProcessInfo(0, 0, 0, 0, rect);
220
		GetClientSize(width, height, rect[2], rect[3], thread_data);
221
	}
222
 
223
	inline void GetClientSize(unsigned short &width, unsigned short &height, int win_width, int win_height)
224
	{
225
		GetClientSize(width, height, win_width, win_height, GetThreadData());
226
	}
227
 
228
	inline void GetTimeDate(int t[/* 6 */]) {GetTime(t); GetDate(t + 3);}
229
 
230
	inline void InitMutex(TMutex *mutex) {mutex->mut = 0;}
231
 
232
	inline void InitRecMutex(TRecMutex *mutex) {mutex->mut = 0; mutex->pid = -1;}
233
 
234
	inline bool TryLock(TRecMutex *mutex) {return TryLock(mutex, GetPid());}
235
 
236
	inline bool TryLock(TRecMutex *mutex, TThreadData thread_data) {return TryLock(mutex, GetPid(thread_data));}
237
 
238
	inline void Lock(TRecMutex *mutex) {Lock(mutex, GetPid());}
239
 
240
	inline void Lock(TRecMutex *mutex, TThreadData thread_data) {Lock(mutex, GetPid(thread_data));}
241
 
242
	inline bool LockTime(TRecMutex *mutex, int time) {return LockTime(mutex, time, GetPid());}
243
 
244
	inline bool LockTime(TRecMutex *mutex, int time, TThreadData thread_data)
245
				{return LockTime(mutex, time, GetPid(thread_data));}
246
 
247
	inline void UnLock(TRecMutex *mutex) {UnLock(mutex, GetPid());}
248
 
249
	inline void UnLock(TRecMutex *mutex, TThreadData thread_data) {UnLock(mutex, GetPid(thread_data));}
250
 
251
	inline int GetThreadNumber() {return _ThreadNumber;}
252
 
253
// Constants from fasm.
254
 
8184 IgorA 255
#include "kos_func.inc"
8129 IgorA 256
 
257
// Functions.
258
 
259
	unsigned char _HashByte(unsigned int value);
260
	unsigned short _HashWord(unsigned int value);
261
	unsigned int _HashDword(unsigned int value);
262
 
263
	void _GetStartData(TStartData &start_data, TThreadData thread_data)
264
	{
8133 IgorA 265
		start_data.Left = (unsigned short)((unsigned long)thread_data[KOLIBRI_THREAD_DATA_X] >> 16);
266
		start_data.Width = (unsigned short)((unsigned long)thread_data[KOLIBRI_THREAD_DATA_X]);
267
		start_data.Top = (unsigned short)((unsigned long)thread_data[KOLIBRI_THREAD_DATA_Y] >> 16);
268
		start_data.Height = (unsigned short)((unsigned long)thread_data[KOLIBRI_THREAD_DATA_Y]);
8129 IgorA 269
		GetWindowData(start_data.WinData, thread_data);
270
	}
271
 
272
	void _SetStartData(const TStartData &start_data, TThreadData thread_data)
273
	{
8133 IgorA 274
		(unsigned long&)thread_data[KOLIBRI_THREAD_DATA_X] =
8129 IgorA 275
					((unsigned int)start_data.Left << 16) | start_data.Width;
8133 IgorA 276
		(unsigned long&)thread_data[KOLIBRI_THREAD_DATA_Y] =
8129 IgorA 277
					((unsigned int)start_data.Top << 16) | start_data.Height;
278
		SetWindowData(start_data.WinData, thread_data);
279
	}
280
 
281
	void _ApplyCommonColors(TWindowData &win_data)
282
	{
283
		unsigned int colors[10];
284
		ReadCommonColors(colors);
285
		win_data.WindowColor = colors[5];
286
		win_data.HeaderColor = colors[1];
287
		win_data.BorderColor = colors[0];
288
		win_data.TitleColor = colors[4];
289
	}
290
 
291
	void _SetValueFunctionPriority(void *beg, int n)
292
	{
293
		int k, i;
294
		unsigned char num[256];
295
		for (i = 0; i < 256; i++) num[i] = 0;
296
		for (k = 0; k < n; k++)
297
		{
298
			i = ((unsigned char*)beg + 6*k)[1];
299
			((unsigned char*)beg + 6*k)[0] = num[i];
300
			if (num[i] != 255) num[i]++;
301
		}
302
	}
303
 
304
	void _CallFunctionPriority(void *beg, void *end, bool reverse = false)
305
	{
306
		struct _Local
307
		{
308
			static int cmp(void *beg, int i, int j)
309
			{
310
				unsigned char *x = (unsigned char*)beg + 6*i;
311
				unsigned char *y = (unsigned char*)beg + 6*j;
312
				if (*(unsigned short*)x < *(unsigned short*)y) return -1;
313
				if (*(unsigned short*)x > *(unsigned short*)y) return 1;
314
				return 0;
315
			}
316
 
317
			static void swap(void *beg, int i, int j)
318
			{
319
				unsigned char *x = (unsigned char*)beg + 6*i;
320
				unsigned char *y = (unsigned char*)beg + 6*j;
321
				short s;
322
				int t;
323
				s = *(short*)x; *(short*)x = *(short*)y; *(short*)y = s;
324
				x += 2; y += 2;
325
				t = *(int*)x; *(int*)x = *(int*)y; *(int*)y = t;
326
			}
327
 
328
			static void call(void *beg, int i)
329
			{
330
				unsigned char *x = (unsigned char*)beg + 6*i;
331
				(*(void(**)())(x+2))();
332
			}
333
		};
334
 
335
		if (!beg || !end || end <= beg) return;
336
		int i, j, k, m, n;
337
		n = ((unsigned char*)end - (unsigned char*)beg) / 6;
338
		if (n <= 0) return;
339
		_SetValueFunctionPriority(beg, n);
340
		m = n; k = n;
341
		while (m > 1)
342
		{
343
			if (k > 0) k--;
344
			else _Local::swap(beg, 0, --m);
345
			j = k;
346
			for (;;)
347
			{
348
				 i = j;
349
				 if (2*i + 1 >= m) break;
350
				 if (_Local::cmp(beg, 2*i + 1, j) > 0) j = 2*i + 1;
351
				 if (2*i + 2 < m && _Local::cmp(beg, 2*i + 2, j) > 0) j = 2*i + 2;
352
				 if (i == j) break;
353
				 _Local::swap(beg, i, j);
354
			}
355
		}
356
		if (!reverse)
357
		{
358
			for (k = 0; k < n; k++) _Local::call(beg, k);
359
		}
360
		else
361
		{
362
			for (k = n-1; k >= 0; k--) _Local::call(beg, k);
363
		}
364
	}
365
 
366
	bool _CallStart(TThreadData thread_data, void *init = 0, void *init_end = 0)
367
	{
368
		struct _TThreadDataTemplate
369
		{
370
			unsigned int data[12];
371
		};
372
		static const _TThreadDataTemplate _ThreadDataTemplate =
373
			{{3, 0x00320100, 0x00320100, 0x03FFFFFF, 0x806060FF, 0x00000000, 0x00FFFF40, 0, 0, 0, -1, -1}};
374
 
375
		unsigned int pid = GetPid();
376
		volatile TThreadData *thread_table_item;
377
		Lock(&_ThreadMutex);
378
		if (_ExitProcessNow) ExitProcess();
379
		thread_table_item = &_ThreadTable[_HashByte(pid)];
8133 IgorA 380
		thread_data[KOLIBRI_THREAD_DATA_NEXT] = (void*)*thread_table_item;
381
		(unsigned int&)thread_data[KOLIBRI_THREAD_DATA_PID] = pid;
382
		*(_TThreadDataTemplate*)(thread_data + KOLIBRI_THREAD_DATA_FLAG) = _ThreadDataTemplate;
8129 IgorA 383
		*thread_table_item = thread_data;
384
		UnLock(&_ThreadMutex);
385
		if (_ExitProcessNow) ExitProcess();
386
		_CallFunctionPriority(init, init_end, false);
387
		TStartData start_data;
388
		_GetStartData(start_data, thread_data);
389
		_ApplyCommonColors(start_data.WinData);
8133 IgorA 390
		(unsigned int&)thread_data[KOLIBRI_THREAD_DATA_FLAG] |= 0x40000000;
391
		thread_data[KOLIBRI_THREAD_DATA_TITLE] = (void*)(&start_data);
392
		if (!KolibriOnStart(start_data, thread_data)) return false;
393
		(unsigned int&)thread_data[KOLIBRI_THREAD_DATA_FLAG] &= ~0x40000000;
8129 IgorA 394
		_SetStartData(start_data, thread_data);
395
		return true;
396
	}
397
 
398
	void _RemoveThreadData(TThreadData thread_data, void *exit = 0, void *exit_end = 0)
399
	{
400
		_CallFunctionPriority(exit, exit_end, true);
401
		volatile TThreadData *thread_table_item;
402
		Lock(&_ThreadMutex);
403
		if (_ExitProcessNow) ExitProcess();
404
		thread_table_item = &_ThreadTable[_HashByte(GetPid(thread_data))];
405
		while (*thread_table_item)
406
		{
407
			if (*thread_table_item == thread_data)
408
			{
8133 IgorA 409
				*thread_table_item = (TThreadData)thread_data[KOLIBRI_THREAD_DATA_NEXT];
8129 IgorA 410
				break;
411
			}
8133 IgorA 412
			thread_table_item = (TThreadData*)(*thread_table_item + KOLIBRI_THREAD_DATA_NEXT);
8129 IgorA 413
		}
414
		UnLock(&_ThreadMutex);
415
		if (_ExitProcessNow) ExitProcess();
416
	}
417
 
418
	void GetWindowData(TWindowData &win_data, TThreadData thread_data)
419
	{
8133 IgorA 420
		if ((unsigned int)thread_data[KOLIBRI_THREAD_DATA_FLAG] & 0x40000000)
8129 IgorA 421
		{
8133 IgorA 422
			win_data = ((TStartData*)thread_data[KOLIBRI_THREAD_DATA_TITLE])->WinData;
8129 IgorA 423
			return;
424
		}
8133 IgorA 425
		win_data.WindowType = (unsigned short)((unsigned int)thread_data[KOLIBRI_THREAD_DATA_C_WINDOW] >> 24);
426
		win_data.HeaderType = (unsigned short)((unsigned int)thread_data[KOLIBRI_THREAD_DATA_C_HEADER] >> 24);
427
		win_data.WindowColor = (unsigned int)thread_data[KOLIBRI_THREAD_DATA_C_WINDOW] & 0xFFFFFF;
428
		win_data.HeaderColor = (unsigned int)thread_data[KOLIBRI_THREAD_DATA_C_HEADER] & 0xFFFFFF;
429
		win_data.BorderColor = (unsigned int)thread_data[KOLIBRI_THREAD_DATA_C_BORDER] & 0xFFFFFF;
430
		win_data.TitleColor = (unsigned int)thread_data[KOLIBRI_THREAD_DATA_C_TITLE] & 0xFFFFFF;
431
		win_data.Title = (char*)thread_data[KOLIBRI_THREAD_DATA_TITLE];
8129 IgorA 432
	}
433
 
434
	void SetWindowData(const TWindowData &win_data, TThreadData thread_data)
435
	{
8133 IgorA 436
		if ((unsigned int)thread_data[KOLIBRI_THREAD_DATA_FLAG] & 0x40000000)
8129 IgorA 437
		{
8133 IgorA 438
			((TStartData*)thread_data[KOLIBRI_THREAD_DATA_TITLE])->WinData = win_data;
8129 IgorA 439
			return;
440
		}
8133 IgorA 441
		(unsigned int&)thread_data[KOLIBRI_THREAD_DATA_C_WINDOW] =
8129 IgorA 442
					((unsigned int)win_data.WindowType << 24) | (win_data.WindowColor & 0xFFFFFF);
8133 IgorA 443
		(unsigned int&)thread_data[KOLIBRI_THREAD_DATA_C_HEADER] =
8129 IgorA 444
					((unsigned int)win_data.HeaderType << 24) | (win_data.HeaderColor & 0xFFFFFF);
8133 IgorA 445
		(unsigned int&)thread_data[KOLIBRI_THREAD_DATA_C_BORDER] = win_data.BorderColor & 0xFFFFFF;
446
		(unsigned int&)thread_data[KOLIBRI_THREAD_DATA_C_TITLE] = win_data.TitleColor & 0xFFFFFF;
447
		thread_data[KOLIBRI_THREAD_DATA_TITLE] = (void*)win_data.Title;
8129 IgorA 448
		Invalidate(1, thread_data);
449
	}
450
 
451
	void CloseWindow(TThreadData thread_data)
452
	{
8133 IgorA 453
		(unsigned int&)thread_data[KOLIBRI_THREAD_DATA_FLAG] |= 0x80000000;
8129 IgorA 454
	}
455
 
456
	void Invalidate(int frame, TThreadData thread_data)
457
	{
458
		if (frame < 0) return;
8133 IgorA 459
		(unsigned int&)thread_data[KOLIBRI_THREAD_DATA_FLAG] |= (frame ? 3 : 1);
8129 IgorA 460
	}
461
 
462
	void* GetPicture(unsigned short &width, unsigned short &height, TThreadData thread_data)
463
	{
8133 IgorA 464
		width = (unsigned short)((unsigned int)thread_data[KOLIBRI_THREAD_DATA_SZ_PICT] >> 16);
465
		height = (unsigned short)((unsigned int)thread_data[KOLIBRI_THREAD_DATA_SZ_PICT]);
466
		return (void*)thread_data[KOLIBRI_THREAD_DATA_PICTURE];
8129 IgorA 467
	}
468
 
469
	void SetPicture(void *picture, unsigned short width, unsigned short height, TThreadData thread_data)
470
	{
8133 IgorA 471
		thread_data[KOLIBRI_THREAD_DATA_PICTURE] = (void*)picture;
472
		(unsigned int&)thread_data[KOLIBRI_THREAD_DATA_SZ_PICT] =
8129 IgorA 473
					(width == 0 || height == 0) ? 0 : (((unsigned int)width << 16) | height);
474
		Invalidate(0, thread_data);
475
	}
476
 
477
	int _GetSkinHeader();
478
 
479
	void GetBorderHeader(unsigned short &border_size, unsigned short &header_size, TThreadData thread_data)
480
	{
8133 IgorA 481
		int win_type = ((unsigned int)thread_data[KOLIBRI_THREAD_DATA_FLAG] & 0x40000000) ?
482
			((TStartData*)thread_data[KOLIBRI_THREAD_DATA_TITLE])->WinData.WindowType :
483
		   ((unsigned int)thread_data[KOLIBRI_THREAD_DATA_C_WINDOW] >> 24);
8170 IgorA 484
		border_size = KOLIBRI_BORDER_SIZE;
485
		header_size = short(((win_type & 15) == 3) ? _GetSkinHeader() : KOLIBRI_HEADER_SIZE);
8129 IgorA 486
	}
487
 
488
	void GetClientSize(unsigned short &width, unsigned short &height,
489
						int win_width, int win_height, TThreadData thread_data)
490
	{
491
		const int MAX_SIZE = 32767;
492
		unsigned short border_size, header_size;
493
		GetBorderHeader(border_size, header_size, thread_data);
494
		win_width -= 2 * border_size;
495
		win_height -= border_size + header_size;
496
		if (win_width < 0) win_width = 0;
497
		else if (win_width > MAX_SIZE) win_width = MAX_SIZE;
498
		if (win_height < 0) win_height = 0;
499
		else if (win_height > MAX_SIZE) win_height = MAX_SIZE;
500
		width = (unsigned short)win_width;
501
		height = (unsigned short)win_height;
502
	}
503
 
504
	void GetMousePosPicture(short &x, short &y)
505
	{
506
		unsigned short dx, dy;
507
		GetMousePosition(x, y);
508
		GetBorderHeader(dx, dy);
509
		x -= dx; y -= dy;
510
	}
511
}
512
 
8170 IgorA 513
#endif  // else: def __KOLIBRI__
8129 IgorA 514
 
8133 IgorA 515
#endif  // ndef __KOLIBRI_H_INCLUDED_
8129 IgorA 516