fd91e883b2f446b53958921cd8f263208ac10b24
[tpg/acess2.git] / Usermode / Applications / axwin3_src / libaxwin3.so_src / wm.c
1 /*
2  * AxWin3 Interface Library
3  * - By John Hodge (thePowersGang)
4  *
5  * wm.c
6  * - Core window management functions
7  */
8 #include <axwin3/axwin.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include "include/internal.h"
12 #include "include/ipc.h"
13
14 #define WINDOWS_PER_ALLOC       (63)
15
16 typedef struct sWindowBlock     tWindowBlock;
17
18 typedef struct sAxWin3_Window   tWindow;
19
20 // === STRUCTURES ===
21 struct sWindowBlock
22 {
23         tWindowBlock    *Next;
24         tWindow *Windows[WINDOWS_PER_ALLOC];
25 };
26
27 // === GLOBALS ===
28  int    giAxWin3_LowestFreeWinID;
29  int    giAxWin3_HighestUsedWinID;
30 tWindowBlock    gAxWin3_WindowList;
31
32 // === CODE ===
33 tWindow *AxWin3_int_CreateWindowStruct(uint32_t ServerID, int ExtraBytes)
34 {
35         tWindow *ret;
36         
37         ret = calloc(sizeof(tWindow) + ExtraBytes, 1);
38         ret->ServerID = ServerID;
39
40         return ret;
41 }
42
43 tWindow *AxWin3_int_GetWindowFromID(uint32_t ServerID)
44 {
45         tWindowBlock    *block = &gAxWin3_WindowList;
46         while(block && ServerID > WINDOWS_PER_ALLOC) {
47                 block = block->Next;
48                 ServerID -= WINDOWS_PER_ALLOC;
49         }
50         if(!block)      return NULL;
51         return block->Windows[ServerID];
52 }
53
54 tWindow *AxWin3_int_AllocateWindowInfo(int DataBytes, int *WinID)
55 {
56          int    idx, newWinID;
57         tWindowBlock *block, *prev;
58         tWindow *ret;   
59
60         block = &gAxWin3_WindowList;
61         newWinID = giAxWin3_LowestFreeWinID;
62         for( idx = 0; block; newWinID ++ )
63         {
64                 if( block->Windows[idx] == NULL )
65                         break;
66                 idx ++;
67                 if(idx == WINDOWS_PER_ALLOC) {
68                         prev = block;
69                         block = block->Next;
70                         idx = 0;
71                 }
72         }
73         
74         if( !block )
75         {
76                 block = calloc(sizeof(tWindowBlock), 1);
77                 prev->Next = block;
78                 idx = 0;
79         }
80         
81         ret = block->Windows[idx] = AxWin3_int_CreateWindowStruct(newWinID, DataBytes);
82         if(newWinID > giAxWin3_HighestUsedWinID)
83                 giAxWin3_HighestUsedWinID = newWinID;
84         if(newWinID == giAxWin3_LowestFreeWinID)
85                 giAxWin3_HighestUsedWinID ++;
86
87         if(WinID)       *WinID = newWinID;
88
89         return ret;
90 }
91
92 tHWND AxWin3_CreateWindow(
93         tHWND Parent, const char *Renderer, int RendererArg,
94         int DataBytes, tAxWin3_WindowMessageHandler MessageHandler
95         )
96 {
97         tWindow *ret;
98          int    newWinID;
99          int    dataSize = sizeof(tIPCMsg_CreateWin) + strlen(Renderer) + 1;
100         tAxWin_IPCMessage       *msg;
101         tIPCMsg_CreateWin       *create_win;
102
103         // Allocate a window ID
104         ret = AxWin3_int_AllocateWindowInfo(DataBytes, &newWinID);
105         if(!ret)        return NULL;
106         ret->Handler = MessageHandler;
107
108         // Create message
109         msg = AxWin3_int_AllocateIPCMessage(Parent, IPCMSG_CREATEWIN, 0, dataSize);
110         create_win = (void*)msg->Data;  
111         create_win->NewWinID = newWinID;
112         create_win->RendererArg = RendererArg;
113         strcpy(create_win->Renderer, Renderer);
114
115         // Send and clean up
116         AxWin3_int_SendIPCMessage(msg);
117         free(msg);
118
119         // TODO: Detect and handle possible errors
120
121         // Return success
122         return ret;
123 }
124
125 void AxWin3_DestroyWindow(tHWND Window)
126 {
127         tAxWin_IPCMessage       *msg;
128         
129         msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_DESTROYWIN, 0, 0);
130         AxWin3_int_SendIPCMessage(msg);
131         free(msg);
132 }
133
134 void *AxWin3_int_GetDataPtr(tHWND Window)
135 {
136         return Window->Data;
137 }
138
139 void AxWin3_int_HandleMessage(tAxWin_IPCMessage *Msg)
140 {
141         tWindow *dest;
142
143         dest = AxWin3_int_GetWindowFromID(Msg->Window);
144
145         switch(Msg->ID)
146         {
147         case IPCMSG_SENDMSG: {
148                 tIPCMsg_SendMsg *info = (void*)Msg->Data;
149                 if(Msg->Size < sizeof(*info))   return ;
150                 if(Msg->Size < sizeof(*info) + info->Length)    return ;
151                 if(!dest || !dest->Handler)     return ;
152                 dest->Handler(dest, info->ID, info->Length, info->Data);
153                 break; }
154         }
155 }
156
157 void AxWin3_SendMessage(tHWND Window, tHWND Destination, int Message, int Length, void *Data)
158 {
159         tAxWin_IPCMessage       *msg;
160         tIPCMsg_SendMsg *info;
161         
162         msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_SENDMSG, 0, sizeof(*info)+Length);
163         info = (void*)msg->Data;
164         info->Remote = AxWin3_int_GetWindowID(Destination);
165         info->ID = Message;
166         info->Length = Length;
167         memcpy(info->Data, Data, Length);
168         
169         AxWin3_int_SendIPCMessage(msg);
170         free(msg);
171 }
172
173 void AxWin3_ShowWindow(tHWND Window, int bShow)
174 {
175         tAxWin_IPCMessage       *msg;
176         tIPCMsg_ShowWindow      *info;
177
178         msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_SHOWWINDOW, 0, sizeof(*info));
179         info = (void*)msg->Data;
180         info->bShow = !!bShow;
181         
182         AxWin3_int_SendIPCMessage(msg);
183         
184         free(msg);
185 }
186
187 void AxWin3_SetWindowPos(tHWND Window, short X, short Y, short W, short H)
188 {
189         tAxWin_IPCMessage       *msg;
190         tIPCMsg_SetWindowPos    *info;
191         
192         msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_SETWINPOS, 0, sizeof(*info));
193         info = (void*)msg->Data;
194
195         info->bSetPos = 1;
196         info->bSetDims = 1;
197         info->X = X;    info->Y = Y;
198         info->W = W;    info->H = H;
199
200         AxWin3_int_SendIPCMessage(msg); 
201         free(msg);
202 }
203
204 void AxWin3_MoveWindow(tHWND Window, short X, short Y)
205 {
206         tAxWin_IPCMessage       *msg;
207         tIPCMsg_SetWindowPos    *info;
208         
209         msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_SETWINPOS, 0, sizeof(*info));
210         info = (void*)msg->Data;
211
212         info->bSetPos = 1;
213         info->bSetDims = 0;
214         info->X = X;
215         info->Y = Y;
216         
217         AxWin3_int_SendIPCMessage(msg);
218         
219         free(msg);
220 }
221
222 void AxWin3_ResizeWindow(tHWND Window, short W, short H)
223 {
224         tAxWin_IPCMessage       *msg;
225         tIPCMsg_SetWindowPos    *info;
226         
227         msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_SETWINPOS, 0, sizeof(*info));
228         info = (void*)msg->Data;
229
230         info->bSetPos = 0;
231         info->bSetDims = 1;
232         info->W = W;
233         info->H = H;
234         
235         AxWin3_int_SendIPCMessage(msg);
236         
237         free(msg);
238 }
239

UCC git Repository :: git.ucc.asn.au