Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. #ifndef __MENUET_H_INCLUDED_
  2. #define __MENUET_H_INCLUDED_
  3.  
  4. #include <me_lib.h>
  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 <me_func.inc>
  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.  
  537.