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