Rev 8165 | Rev 8283 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
8140 | IgorA | 1 | #ifndef __KOLIBRI_H_INCLUDED_ |
2 | #define __KOLIBRI_H_INCLUDED_ |
||
3 | |||
4 | #include "kos_lib.h" |
||
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: "; |
||
8236 | IgorA | 11 | char CommandLine[4096]; |
8140 | 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 | |||
20 | struct TStartData // This structure is used only for KolibriOnStart function. |
||
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. |
||
31 | #define KOLIBRI_MUTEX_INIT {} // Simple mutex initializer, cat be redefined in a realization of the library |
||
32 | |||
33 | struct TRecMutex; // Recursive mutex can be locked many times by a single thread at a time. |
||
34 | #define KOLIBRI_REC_MUTEX_INIT {} // Recursive mutex initializer, cat be redefined in a realization of the library |
||
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. |
||
8153 | maxcodehac | 40 | void DrawButton(long id, long color, long x, long y, long c_x, long c_y); // Draw Standard button |
8140 | 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 | |||
8165 | IgorA | 58 | void ExitDebug(); // Abnormally terminate a program. |
59 | void ExitProcess(); // Exit from the process, don't call any destructors of global varyables |
||
8140 | 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 |
||
63 | void ReturnMessageLoop(TThreadData thread_data); //_ if it is called from (KolibriOnStart). |
||
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. |
||
137 | void DrawText(short x, short y, int color, const char* string); |
||
8236 | IgorA | 138 | void PutImage(unsigned char* img_data, long img_l, long img_t, long img_w, long img_h); |
8165 | IgorA | 139 | void SetWindowCaption(const char* caption); |
8140 | IgorA | 140 | } |
141 | |||
142 | // Function, defined outside. |
||
143 | |||
144 | bool KolibriOnStart(Kolibri::TStartData &me_start, Kolibri::TThreadData thread_data); |
||
145 | // Window will be created iff return value is true. |
||
146 | bool KolibriOnClose(Kolibri::TThreadData thread_data); // Window will be closed iff return value is true. |
||
147 | int KolibriOnIdle(Kolibri::TThreadData thread_data); // Return the time to wait next message. |
||
148 | void KolibriOnSize(int window_rect[/* 4 */], Kolibri::TThreadData thread_data); // When the window is resized. |
||
149 | void KolibriOnKeyPress(Kolibri::TThreadData thread_data); // When user press a key. |
||
150 | void KolibriOnMouse(Kolibri::TThreadData thread_data); // When user move a mouse. |
||
8165 | IgorA | 151 | void KolibriOnButton(long id, Kolibri::TThreadData th); |
8140 | IgorA | 152 | |
153 | #ifdef __KOLIBRI__ |
||
154 | |||
155 | namespace Kolibri |
||
156 | { |
||
157 | // Structures. |
||
158 | |||
159 | struct TMutex // Simple mutex can be locked only once at a time. |
||
160 | { |
||
161 | unsigned int mut; |
||
162 | }; |
||
163 | #undef KOLIBRI_MUTEX_INIT |
||
164 | #define KOLIBRI_MUTEX_INIT {0x40} // Simple mutex initializer, cat be redefined in a realization of the library |
||
165 | |||
166 | struct TRecMutex // Recursive mutex can be locked many times by a single thread at a time. |
||
167 | { |
||
168 | unsigned int mut, pid; |
||
169 | }; |
||
170 | #undef KOLIBRI_REC_MUTEX_INIT |
||
171 | #define KOLIBRI_REC_MUTEX_INIT {0x20,-1} // Recursive mutex initializer, cat be redefined in a realization of the library |
||
172 | |||
173 | // Global variables. |
||
174 | |||
175 | volatile TThreadData _ThreadTable[256]; |
||
176 | volatile unsigned int _ThreadScanCount[2] = {0, 0}; |
||
177 | volatile int _ThreadNumber = 1; |
||
178 | volatile int _ExitProcessNow = 0; |
||
179 | TMutex _ThreadMutex = KOLIBRI_MUTEX_INIT; |
||
180 | unsigned int _ThreadSavedBegProc[4]; |
||
181 | |||
182 | // Inline functions. |
||
183 | |||
184 | inline void GetWindowData(TWindowData &win_data) {GetWindowData(win_data, GetThreadData());} |
||
185 | |||
186 | inline void SetWindowData(const TWindowData &win_data) {SetWindowData(win_data, GetThreadData());} |
||
187 | |||
188 | inline void CloseWindow() {CloseWindow(GetThreadData());} |
||
189 | |||
190 | inline void Redraw(int frame) {Redraw(frame, GetThreadData());} |
||
191 | |||
192 | inline void Invalidate(int frame) {Invalidate(frame, GetThreadData());} |
||
193 | |||
194 | inline void* GetPicture(unsigned short &width, unsigned short &height) |
||
195 | { |
||
196 | return GetPicture(width, height, GetThreadData()); |
||
197 | } |
||
198 | |||
199 | inline void SetPicture(void *picture, unsigned short width, unsigned short height) |
||
200 | { |
||
201 | SetPicture(picture, width, height, GetThreadData()); |
||
202 | } |
||
203 | |||
204 | inline void GetBorderHeader(unsigned short &border_size, unsigned short &header_size) |
||
205 | { |
||
206 | GetBorderHeader(border_size, header_size, GetThreadData()); |
||
207 | } |
||
208 | |||
209 | inline void GetClientSize(unsigned short &width, unsigned short &height) |
||
210 | { |
||
211 | unsigned int pid; |
||
212 | int rect[4]; |
||
213 | GetProcessInfo(0, 0, 0, &pid, rect); |
||
214 | GetClientSize(width, height, rect[2], rect[3], GetThreadData(pid)); |
||
215 | } |
||
216 | |||
217 | inline void GetClientSize(unsigned short &width, unsigned short &height, TThreadData thread_data) |
||
218 | { |
||
219 | int rect[4]; |
||
220 | GetProcessInfo(0, 0, 0, 0, rect); |
||
221 | GetClientSize(width, height, rect[2], rect[3], thread_data); |
||
222 | } |
||
223 | |||
224 | inline void GetClientSize(unsigned short &width, unsigned short &height, int win_width, int win_height) |
||
225 | { |
||
226 | GetClientSize(width, height, win_width, win_height, GetThreadData()); |
||
227 | } |
||
228 | |||
229 | inline void GetTimeDate(int t[/* 6 */]) {GetTime(t); GetDate(t + 3);} |
||
230 | |||
231 | inline void InitMutex(TMutex *mutex) {mutex->mut = 0;} |
||
232 | |||
233 | inline void InitRecMutex(TRecMutex *mutex) {mutex->mut = 0; mutex->pid = -1;} |
||
234 | |||
235 | inline bool TryLock(TRecMutex *mutex) {return TryLock(mutex, GetPid());} |
||
236 | |||
237 | inline bool TryLock(TRecMutex *mutex, TThreadData thread_data) {return TryLock(mutex, GetPid(thread_data));} |
||
238 | |||
239 | inline void Lock(TRecMutex *mutex) {Lock(mutex, GetPid());} |
||
240 | |||
241 | inline void Lock(TRecMutex *mutex, TThreadData thread_data) {Lock(mutex, GetPid(thread_data));} |
||
242 | |||
243 | inline bool LockTime(TRecMutex *mutex, int time) {return LockTime(mutex, time, GetPid());} |
||
244 | |||
245 | inline bool LockTime(TRecMutex *mutex, int time, TThreadData thread_data) |
||
246 | {return LockTime(mutex, time, GetPid(thread_data));} |
||
247 | |||
248 | inline void UnLock(TRecMutex *mutex) {UnLock(mutex, GetPid());} |
||
249 | |||
250 | inline void UnLock(TRecMutex *mutex, TThreadData thread_data) {UnLock(mutex, GetPid(thread_data));} |
||
251 | |||
252 | inline int GetThreadNumber() {return _ThreadNumber;} |
||
253 | |||
254 | // Constants from fasm. |
||
255 | |||
256 | #include "kos_func.inc" |
||
257 | |||
258 | // Functions. |
||
259 | |||
260 | unsigned char _HashByte(unsigned int value); |
||
261 | unsigned short _HashWord(unsigned int value); |
||
262 | unsigned int _HashDword(unsigned int value); |
||
263 | |||
264 | void _GetStartData(TStartData &start_data, TThreadData thread_data) |
||
265 | { |
||
266 | start_data.Left = (unsigned short)((unsigned long)thread_data[KOLIBRI_THREAD_DATA_X] >> 16); |
||
267 | start_data.Width = (unsigned short)((unsigned long)thread_data[KOLIBRI_THREAD_DATA_X]); |
||
268 | start_data.Top = (unsigned short)((unsigned long)thread_data[KOLIBRI_THREAD_DATA_Y] >> 16); |
||
269 | start_data.Height = (unsigned short)((unsigned long)thread_data[KOLIBRI_THREAD_DATA_Y]); |
||
270 | GetWindowData(start_data.WinData, thread_data); |
||
271 | } |
||
272 | |||
273 | void _SetStartData(const TStartData &start_data, TThreadData thread_data) |
||
274 | { |
||
275 | (unsigned long&)thread_data[KOLIBRI_THREAD_DATA_X] = |
||
276 | ((unsigned int)start_data.Left << 16) | start_data.Width; |
||
277 | (unsigned long&)thread_data[KOLIBRI_THREAD_DATA_Y] = |
||
278 | ((unsigned int)start_data.Top << 16) | start_data.Height; |
||
279 | SetWindowData(start_data.WinData, thread_data); |
||
280 | } |
||
281 | |||
282 | void _ApplyCommonColors(TWindowData &win_data) |
||
283 | { |
||
284 | unsigned int colors[10]; |
||
285 | ReadCommonColors(colors); |
||
286 | win_data.WindowColor = colors[5]; |
||
287 | win_data.HeaderColor = colors[1]; |
||
288 | win_data.BorderColor = colors[0]; |
||
289 | win_data.TitleColor = colors[4]; |
||
290 | } |
||
291 | |||
292 | void _SetValueFunctionPriority(void *beg, int n) |
||
293 | { |
||
294 | int k, i; |
||
295 | unsigned char num[256]; |
||
296 | for (i = 0; i < 256; i++) num[i] = 0; |
||
297 | for (k = 0; k < n; k++) |
||
298 | { |
||
299 | i = ((unsigned char*)beg + 6*k)[1]; |
||
300 | ((unsigned char*)beg + 6*k)[0] = num[i]; |
||
301 | if (num[i] != 255) num[i]++; |
||
302 | } |
||
303 | } |
||
304 | |||
305 | void _CallFunctionPriority(void *beg, void *end, bool reverse = false) |
||
306 | { |
||
307 | struct _Local |
||
308 | { |
||
309 | static int cmp(void *beg, int i, int j) |
||
310 | { |
||
311 | unsigned char *x = (unsigned char*)beg + 6*i; |
||
312 | unsigned char *y = (unsigned char*)beg + 6*j; |
||
313 | if (*(unsigned short*)x < *(unsigned short*)y) return -1; |
||
314 | if (*(unsigned short*)x > *(unsigned short*)y) return 1; |
||
315 | return 0; |
||
316 | } |
||
317 | |||
318 | static void swap(void *beg, int i, int j) |
||
319 | { |
||
320 | unsigned char *x = (unsigned char*)beg + 6*i; |
||
321 | unsigned char *y = (unsigned char*)beg + 6*j; |
||
322 | short s; |
||
323 | int t; |
||
324 | s = *(short*)x; *(short*)x = *(short*)y; *(short*)y = s; |
||
325 | x += 2; y += 2; |
||
326 | t = *(int*)x; *(int*)x = *(int*)y; *(int*)y = t; |
||
327 | } |
||
328 | |||
329 | static void call(void *beg, int i) |
||
330 | { |
||
331 | unsigned char *x = (unsigned char*)beg + 6*i; |
||
332 | (*(void(**)())(x+2))(); |
||
333 | } |
||
334 | }; |
||
335 | |||
336 | if (!beg || !end || end <= beg) return; |
||
337 | int i, j, k, m, n; |
||
338 | n = ((unsigned char*)end - (unsigned char*)beg) / 6; |
||
339 | if (n <= 0) return; |
||
340 | _SetValueFunctionPriority(beg, n); |
||
341 | m = n; k = n; |
||
342 | while (m > 1) |
||
343 | { |
||
344 | if (k > 0) k--; |
||
345 | else _Local::swap(beg, 0, --m); |
||
346 | j = k; |
||
347 | for (;;) |
||
348 | { |
||
349 | i = j; |
||
350 | if (2*i + 1 >= m) break; |
||
351 | if (_Local::cmp(beg, 2*i + 1, j) > 0) j = 2*i + 1; |
||
352 | if (2*i + 2 < m && _Local::cmp(beg, 2*i + 2, j) > 0) j = 2*i + 2; |
||
353 | if (i == j) break; |
||
354 | _Local::swap(beg, i, j); |
||
355 | } |
||
356 | } |
||
357 | if (!reverse) |
||
358 | { |
||
359 | for (k = 0; k < n; k++) _Local::call(beg, k); |
||
360 | } |
||
361 | else |
||
362 | { |
||
363 | for (k = n-1; k >= 0; k--) _Local::call(beg, k); |
||
364 | } |
||
365 | } |
||
366 | |||
367 | bool _CallStart(TThreadData thread_data, void *init = 0, void *init_end = 0) |
||
368 | { |
||
369 | struct _TThreadDataTemplate |
||
370 | { |
||
371 | unsigned int data[12]; |
||
372 | }; |
||
373 | static const _TThreadDataTemplate _ThreadDataTemplate = |
||
374 | {{3, 0x00320100, 0x00320100, 0x33FFFFFF, 0x806060FF, 0x00000000, 0x00FFFF40, 0, 0, 0, -1, -1}}; |
||
375 | |||
376 | unsigned int pid = GetPid(); |
||
377 | volatile TThreadData *thread_table_item; |
||
378 | Lock(&_ThreadMutex); |
||
379 | if (_ExitProcessNow) ExitProcess(); |
||
380 | thread_table_item = &_ThreadTable[_HashByte(pid)]; |
||
381 | thread_data[KOLIBRI_THREAD_DATA_NEXT] = (void*)*thread_table_item; |
||
382 | (unsigned int&)thread_data[KOLIBRI_THREAD_DATA_PID] = pid; |
||
383 | *(_TThreadDataTemplate*)(thread_data + KOLIBRI_THREAD_DATA_FLAG) = _ThreadDataTemplate; |
||
384 | *thread_table_item = thread_data; |
||
385 | UnLock(&_ThreadMutex); |
||
386 | if (_ExitProcessNow) ExitProcess(); |
||
387 | _CallFunctionPriority(init, init_end, false); |
||
388 | TStartData start_data; |
||
389 | _GetStartData(start_data, thread_data); |
||
390 | _ApplyCommonColors(start_data.WinData); |
||
391 | (unsigned int&)thread_data[KOLIBRI_THREAD_DATA_FLAG] |= 0x40000000; |
||
392 | thread_data[KOLIBRI_THREAD_DATA_TITLE] = (void*)(&start_data); |
||
393 | if (!KolibriOnStart(start_data, thread_data)) return false; |
||
394 | (unsigned int&)thread_data[KOLIBRI_THREAD_DATA_FLAG] &= ~0x40000000; |
||
395 | _SetStartData(start_data, thread_data); |
||
396 | return true; |
||
397 | } |
||
398 | |||
399 | void _RemoveThreadData(TThreadData thread_data, void *exit = 0, void *exit_end = 0) |
||
400 | { |
||
401 | _CallFunctionPriority(exit, exit_end, true); |
||
402 | volatile TThreadData *thread_table_item; |
||
403 | Lock(&_ThreadMutex); |
||
404 | if (_ExitProcessNow) ExitProcess(); |
||
405 | thread_table_item = &_ThreadTable[_HashByte(GetPid(thread_data))]; |
||
406 | while (*thread_table_item) |
||
407 | { |
||
408 | if (*thread_table_item == thread_data) |
||
409 | { |
||
410 | *thread_table_item = (TThreadData)thread_data[KOLIBRI_THREAD_DATA_NEXT]; |
||
411 | break; |
||
412 | } |
||
413 | thread_table_item = (TThreadData*)(*thread_table_item + KOLIBRI_THREAD_DATA_NEXT); |
||
414 | } |
||
415 | UnLock(&_ThreadMutex); |
||
416 | if (_ExitProcessNow) ExitProcess(); |
||
417 | } |
||
418 | |||
419 | void GetWindowData(TWindowData &win_data, TThreadData thread_data) |
||
420 | { |
||
421 | if ((unsigned int)thread_data[KOLIBRI_THREAD_DATA_FLAG] & 0x40000000) |
||
422 | { |
||
423 | win_data = ((TStartData*)thread_data[KOLIBRI_THREAD_DATA_TITLE])->WinData; |
||
424 | return; |
||
425 | } |
||
426 | win_data.WindowType = (unsigned short)((unsigned int)thread_data[KOLIBRI_THREAD_DATA_C_WINDOW] >> 24); |
||
427 | win_data.HeaderType = (unsigned short)((unsigned int)thread_data[KOLIBRI_THREAD_DATA_C_HEADER] >> 24); |
||
428 | win_data.WindowColor = (unsigned int)thread_data[KOLIBRI_THREAD_DATA_C_WINDOW] & 0xFFFFFF; |
||
429 | win_data.HeaderColor = (unsigned int)thread_data[KOLIBRI_THREAD_DATA_C_HEADER] & 0xFFFFFF; |
||
430 | win_data.BorderColor = (unsigned int)thread_data[KOLIBRI_THREAD_DATA_C_BORDER] & 0xFFFFFF; |
||
431 | win_data.TitleColor = (unsigned int)thread_data[KOLIBRI_THREAD_DATA_C_TITLE] & 0xFFFFFF; |
||
432 | win_data.Title = (char*)thread_data[KOLIBRI_THREAD_DATA_TITLE]; |
||
433 | } |
||
434 | |||
435 | void SetWindowData(const TWindowData &win_data, TThreadData thread_data) |
||
436 | { |
||
437 | if ((unsigned int)thread_data[KOLIBRI_THREAD_DATA_FLAG] & 0x40000000) |
||
438 | { |
||
439 | ((TStartData*)thread_data[KOLIBRI_THREAD_DATA_TITLE])->WinData = win_data; |
||
440 | return; |
||
441 | } |
||
442 | (unsigned int&)thread_data[KOLIBRI_THREAD_DATA_C_WINDOW] = |
||
443 | ((unsigned int)win_data.WindowType << 24) | (win_data.WindowColor & 0xFFFFFF); |
||
444 | (unsigned int&)thread_data[KOLIBRI_THREAD_DATA_C_HEADER] = |
||
445 | ((unsigned int)win_data.HeaderType << 24) | (win_data.HeaderColor & 0xFFFFFF); |
||
446 | (unsigned int&)thread_data[KOLIBRI_THREAD_DATA_C_BORDER] = win_data.BorderColor & 0xFFFFFF; |
||
447 | (unsigned int&)thread_data[KOLIBRI_THREAD_DATA_C_TITLE] = win_data.TitleColor & 0xFFFFFF; |
||
448 | thread_data[KOLIBRI_THREAD_DATA_TITLE] = (void*)win_data.Title; |
||
449 | Invalidate(1, thread_data); |
||
450 | } |
||
451 | |||
452 | void CloseWindow(TThreadData thread_data) |
||
453 | { |
||
454 | (unsigned int&)thread_data[KOLIBRI_THREAD_DATA_FLAG] |= 0x80000000; |
||
455 | } |
||
456 | |||
457 | void Invalidate(int frame, TThreadData thread_data) |
||
458 | { |
||
459 | if (frame < 0) return; |
||
460 | (unsigned int&)thread_data[KOLIBRI_THREAD_DATA_FLAG] |= (frame ? 3 : 1); |
||
461 | } |
||
462 | |||
463 | void* GetPicture(unsigned short &width, unsigned short &height, TThreadData thread_data) |
||
464 | { |
||
465 | width = (unsigned short)((unsigned int)thread_data[KOLIBRI_THREAD_DATA_SZ_PICT] >> 16); |
||
466 | height = (unsigned short)((unsigned int)thread_data[KOLIBRI_THREAD_DATA_SZ_PICT]); |
||
467 | return (void*)thread_data[KOLIBRI_THREAD_DATA_PICTURE]; |
||
468 | } |
||
469 | |||
470 | void SetPicture(void *picture, unsigned short width, unsigned short height, TThreadData thread_data) |
||
471 | { |
||
472 | thread_data[KOLIBRI_THREAD_DATA_PICTURE] = (void*)picture; |
||
473 | (unsigned int&)thread_data[KOLIBRI_THREAD_DATA_SZ_PICT] = |
||
474 | (width == 0 || height == 0) ? 0 : (((unsigned int)width << 16) | height); |
||
475 | Invalidate(0, thread_data); |
||
476 | } |
||
477 | |||
478 | int _GetSkinHeader(); |
||
479 | |||
480 | void GetBorderHeader(unsigned short &border_size, unsigned short &header_size, TThreadData thread_data) |
||
481 | { |
||
482 | int win_type = ((unsigned int)thread_data[KOLIBRI_THREAD_DATA_FLAG] & 0x40000000) ? |
||
483 | ((TStartData*)thread_data[KOLIBRI_THREAD_DATA_TITLE])->WinData.WindowType : |
||
484 | ((unsigned int)thread_data[KOLIBRI_THREAD_DATA_C_WINDOW] >> 24); |
||
485 | border_size = KOLIBRI_BORDER_SIZE; |
||
486 | header_size = short(((win_type & 15) == 3) ? _GetSkinHeader() : KOLIBRI_HEADER_SIZE); |
||
487 | } |
||
488 | |||
489 | void GetClientSize(unsigned short &width, unsigned short &height, |
||
490 | int win_width, int win_height, TThreadData thread_data) |
||
491 | { |
||
492 | const int MAX_SIZE = 32767; |
||
493 | unsigned short border_size, header_size; |
||
494 | GetBorderHeader(border_size, header_size, thread_data); |
||
495 | win_width -= 2 * border_size; |
||
496 | win_height -= border_size + header_size; |
||
497 | if (win_width < 0) win_width = 0; |
||
498 | else if (win_width > MAX_SIZE) win_width = MAX_SIZE; |
||
499 | if (win_height < 0) win_height = 0; |
||
500 | else if (win_height > MAX_SIZE) win_height = MAX_SIZE; |
||
501 | width = (unsigned short)win_width; |
||
502 | height = (unsigned short)win_height; |
||
503 | } |
||
504 | |||
505 | void GetMousePosPicture(short &x, short &y) |
||
506 | { |
||
507 | unsigned short dx, dy; |
||
508 | GetMousePosition(x, y); |
||
509 | GetBorderHeader(dx, dy); |
||
510 | x -= dx; y -= dy; |
||
511 | } |
||
512 | } |
||
513 | |||
514 | #else // def __KOLIBRI__ |
||
515 | |||
516 | namespace Kolibri |
||
517 | { |
||
518 | struct TMutex |
||
519 | { |
||
520 | unsigned int mut; |
||
521 | |||
522 | TMutex(); |
||
523 | ~TMutex(); |
||
524 | }; |
||
525 | #undef KOLIBRI_MUTEX_INIT |
||
526 | #define KOLIBRI_MUTEX_INIT TMutex() |
||
527 | |||
528 | struct TRecMutex |
||
529 | { |
||
530 | unsigned int mut; |
||
531 | |||
532 | TRecMutex(); |
||
533 | ~TRecMutex(); |
||
534 | }; |
||
535 | #undef KOLIBRI_REC_MUTEX_INIT |
||
536 | #define KOLIBRI_REC_MUTEX_INIT TRecMutex() |
||
537 | } |
||
538 | |||
539 | #endif // else: def __KOLIBRI__ |
||
540 | |||
541 | #endif // ndef __KOLIBRI_H_INCLUDED_>>><>>><>><>>>=>=>>>>><>><> |
||
542 |