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