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 |