2 * AxWin3 Interface Library
3 * - By John Hodge (thePowersGang)
6 * - Core window management functions
8 #include <axwin3/axwin.h>
11 #include "include/internal.h"
12 #include "include/ipc.h"
14 #define WINDOWS_PER_ALLOC (63)
16 typedef struct sWindowBlock tWindowBlock;
18 typedef struct sAxWin3_Window tWindow;
24 tWindow *Windows[WINDOWS_PER_ALLOC];
28 int giAxWin3_LowestFreeWinID;
29 int giAxWin3_HighestUsedWinID;
30 tWindowBlock gAxWin3_WindowList;
33 tWindow *AxWin3_int_CreateWindowStruct(uint32_t ServerID, int ExtraBytes)
37 ret = calloc(sizeof(tWindow) + ExtraBytes, 1);
38 ret->ServerID = ServerID;
43 tWindow *AxWin3_int_GetWindowFromID(uint32_t ServerID)
45 tWindowBlock *block = &gAxWin3_WindowList;
46 while(block && ServerID > WINDOWS_PER_ALLOC) {
48 ServerID -= WINDOWS_PER_ALLOC;
50 if(!block) return NULL;
51 return block->Windows[ServerID];
54 tWindow *AxWin3_int_AllocateWindowInfo(int DataBytes, int *WinID)
57 tWindowBlock *block, *prev = NULL;
60 block = &gAxWin3_WindowList;
61 newWinID = giAxWin3_LowestFreeWinID;
62 for( idx = 0; block; newWinID ++ )
64 if( block->Windows[idx] == NULL )
67 if(idx == WINDOWS_PER_ALLOC) {
76 block = calloc(sizeof(tWindowBlock), 1);
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 ++;
87 if(WinID) *WinID = newWinID;
92 int AxWin3_GetDisplayCount(void)
94 tAxWin_IPCMessage *msg;
95 tIPCMsg_ReturnInt *ret;
98 msg = AxWin3_int_AllocateIPCMessage(NULL, IPCMSG_GETDISPLAYCOUNT, IPCMSG_FLAG_RETURN, 0);
99 AxWin3_int_SendIPCMessage(msg);
102 msg = AxWin3_int_WaitIPCMessage(IPCMSG_GETDISPLAYCOUNT);
103 if(msg->Size < sizeof(*ret)) return -1;
104 ret = (void*)msg->Data;
110 int AxWin3_GetDisplayDims(int Display, int *X, int *Y, int *Width, int *Height)
112 tAxWin_IPCMessage *msg;
113 tIPCMsg_GetDisplayDims *req;
114 tIPCMsg_RetDisplayDims *ret;
116 msg = AxWin3_int_AllocateIPCMessage(NULL, IPCMSG_GETDISPLAYDIMS, IPCMSG_FLAG_RETURN, sizeof(*req));
117 req = (void*)msg->Data;
118 req->DisplayID = Display;
119 AxWin3_int_SendIPCMessage(msg);
122 msg = AxWin3_int_WaitIPCMessage(IPCMSG_GETDISPLAYDIMS);
123 if(msg->Size < sizeof(*ret)) return -1;
124 ret = (void*)msg->Data;
128 if(Width) *Width = ret->W;
129 if(Height) *Height = ret->H;
134 tHWND AxWin3_CreateWindow(
135 tHWND Parent, const char *Renderer, int RendererArg,
136 int DataBytes, tAxWin3_WindowMessageHandler MessageHandler
141 int dataSize = sizeof(tIPCMsg_CreateWin) + strlen(Renderer) + 1;
142 tAxWin_IPCMessage *msg;
143 tIPCMsg_CreateWin *create_win;
145 // Allocate a window ID
146 ret = AxWin3_int_AllocateWindowInfo(DataBytes, &newWinID);
147 if(!ret) return NULL;
148 ret->Handler = MessageHandler;
151 msg = AxWin3_int_AllocateIPCMessage(Parent, IPCMSG_CREATEWIN, 0, dataSize);
152 create_win = (void*)msg->Data;
153 create_win->NewWinID = newWinID;
154 create_win->RendererArg = RendererArg;
155 strcpy(create_win->Renderer, Renderer);
158 AxWin3_int_SendIPCMessage(msg);
161 // TODO: Detect and handle possible errors
167 void AxWin3_DestroyWindow(tHWND Window)
169 tAxWin_IPCMessage *msg;
171 msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_DESTROYWIN, 0, 0);
172 AxWin3_int_SendIPCMessage(msg);
176 void *AxWin3_int_GetDataPtr(tHWND Window)
181 void AxWin3_int_HandleMessage(tAxWin_IPCMessage *Msg)
185 dest = AxWin3_int_GetWindowFromID(Msg->Window);
189 case IPCMSG_SENDMSG: {
190 tIPCMsg_SendMsg *info = (void*)Msg->Data;
191 if(Msg->Size < sizeof(*info)) return ;
192 if(Msg->Size < sizeof(*info) + info->Length) return ;
193 if(!dest || !dest->Handler) return ;
194 dest->Handler(dest, info->ID, info->Length, info->Data);
199 void AxWin3_SetWindowTitle(tHWND Window, const char *Title)
201 tAxWin_IPCMessage *msg;
202 int len = strlen(Title);
204 msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_SETWINTITLE, 0, len+1);
205 strcpy(msg->Data, Title);
207 AxWin3_int_SendIPCMessage(msg);
212 void AxWin3_SendMessage(tHWND Window, tHWND Destination, int Message, int Length, void *Data)
214 tAxWin_IPCMessage *msg;
215 tIPCMsg_SendMsg *info;
217 msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_SENDMSG, 0, sizeof(*info)+Length);
218 info = (void*)msg->Data;
219 info->Remote = AxWin3_int_GetWindowID(Destination);
221 info->Length = Length;
222 memcpy(info->Data, Data, Length);
224 AxWin3_int_SendIPCMessage(msg);
228 void AxWin3_FocusWindow(tHWND Window)
230 tAxWin_IPCMessage *msg;
232 msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_FOCUSWINDOW, 0, 0);
234 AxWin3_int_SendIPCMessage(msg);
238 void AxWin3_ShowWindow(tHWND Window, int bShow)
240 tAxWin_IPCMessage *msg;
241 tIPCMsg_Boolean *info;
243 msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_SHOWWINDOW, 0, sizeof(*info));
244 info = (void*)msg->Data;
245 info->Value = !!bShow;
247 AxWin3_int_SendIPCMessage(msg);
252 void AxWin3_DecorateWindow(tHWND Window, int bDecorate)
254 tAxWin_IPCMessage *msg;
255 tIPCMsg_Boolean *info;
257 msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_DECORATEWINDOW, 0, sizeof(*info));
258 info = (void*)msg->Data;
259 info->Value = !!bDecorate;
261 AxWin3_int_SendIPCMessage(msg);
266 void AxWin3_SetWindowPos(tHWND Window, short X, short Y, short W, short H)
268 tAxWin_IPCMessage *msg;
269 tIPCMsg_SetWindowPos *info;
271 msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_SETWINPOS, 0, sizeof(*info));
272 info = (void*)msg->Data;
276 info->X = X; info->Y = Y;
277 info->W = W; info->H = H;
279 AxWin3_int_SendIPCMessage(msg);
283 void AxWin3_MoveWindow(tHWND Window, short X, short Y)
285 tAxWin_IPCMessage *msg;
286 tIPCMsg_SetWindowPos *info;
288 msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_SETWINPOS, 0, sizeof(*info));
289 info = (void*)msg->Data;
296 AxWin3_int_SendIPCMessage(msg);
301 void AxWin3_ResizeWindow(tHWND Window, short W, short H)
303 tAxWin_IPCMessage *msg;
304 tIPCMsg_SetWindowPos *info;
306 msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_SETWINPOS, 0, sizeof(*info));
307 info = (void*)msg->Data;
314 AxWin3_int_SendIPCMessage(msg);