tHWND gSidebar;
// === CODE ===
+int sidebar_callback(tHWND Window, int Length, void *Data)
+{
+ return 0;
+}
+
int main(int argc, char *argv[])
{
// Connect to AxWin3 Server
// Create sidebar
// TODO: Use the widget library instead
- gSidebar = AxWin3_CreateWindow(NULL, "widget", 0, 0, NULL);
+ gSidebar = AxWin3_CreateWindow(NULL, "Widget", 0, 0, NULL, sidebar_callback);
+
+ // TODO: Get screen dimensions somehow
+
+ // Size the window
+ AxWin3_SetWindowPos(gSidebar, 0, 0, 32, 600);
+ // Show!
+ AxWin3_ShowWindow(gSidebar, 1);
+
// Idle loop
AxWin3_MainLoop();
typedef struct sAxWin_IPCMessage tAxWin_IPCMessage;
typedef struct sIPCMsg_Return tIPCMsg_Return;
typedef struct sIPCMsg_CreateWin tIPCMsg_CreateWin;
+typedef struct sIPCMsg_ShowWindow tIPCMsg_ShowWindow;
+typedef struct sIPCMsg_SetWindowPos tIPCMsg_SetWindowPos;
/**
* \name Flags for IPC Messages
char Renderer[];
};
+struct sIPCMsg_ShowWindow
+{
+ uint32_t bShow;
+};
+
+struct sIPCMsg_SetWindowPos
+{
+ int16_t X;
+ int16_t Y;
+ uint16_t W;
+ uint16_t H;
+ uint8_t Fields;
+};
+
enum eAxWin_IPCMessageTypes
{
- IPCMSG_PING, //!<
- IPCMSG_SENDMSG, //!< Send a message to another window
+ IPCMSG_PING, //!< Get the server version
+ IPCMSG_SENDMSG, //!< Send a message to another window (or to self)
IPCMSG_CREATEWIN, //!< Create a window
+ IPCMSG_DESTROYWIN, //!< Destroy a window
+ IPCMSG_SHOWWINDOW, //!< Show/Hide a window
+ IPCMSG_SETWINPOS, //!< Set a window position
};
#endif
IPC_Msg_CreateWin(client, Msg);
break;
+// case IPCMSG_SHOWWINDOW:
+
// --- Unknown message
default:
fprintf(stderr, "WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType);
- _SysDebug("WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType);
+ _SysDebug("WARNING: Unknown message %i (%p)", Msg->ID, IPCType);
break;
}
}
Input_Init();
Renderer_Widget_Init();
-// WM_Update();
// Spawn interface root
if( clone(CLONE_VM, 0) == 0 )
char *argv[] = {csInterfaceApp, NULL};
sprintf(server_info, "AXWIN3_SERVER=%i", server_tid);
execve(csInterfaceApp, argv, envp);
+ exit(1);
}
// Main Loop
int nfds = 0;
FD_ZERO(&fds);
+ WM_Update();
+
Input_FillSelect(&nfds, &fds);
IPC_FillSelect(&nfds, &fds);
// === GLOBALS ===
tWMRenderer gRenderer_Widget = {
- .Name = "Classful",
+ .Name = "Widget",
.CreateWindow = Renderer_Widget_Create,
.Redraw = Renderer_Widget_Redraw,
.HandleMessage = Renderer_Widget_HandleMessage
// === CODE ===
void WM_RegisterRenderer(tWMRenderer *Renderer)
{
- // TODO: Catch re-adding the first somehow?
- if(Renderer->Next) return;
+ // TODO: Catch out duplicates
Renderer->Next = gpWM_Renderers;
gpWM_Renderers = Renderer;
}
return calloc( sizeof(tWindow) + ExtraSize, 1 );
}
+void WM_Update(void)
+{
+ // - Iterate through visible windows, updating them as needed
+
+ // - Draw windows from back to front to the render buffer
+
+ // - Blit the buffer to the screen
+}
+
void WM_Render_FilledRect(tWindow *Window, tColour Colour, int X, int Y, int W, int H)
{
+ // Clip to window dimensions
+ if(X < 0) { W += X; X = 0; }
+ if(Y < 0) { H += Y; Y = 0; }
+ if(X >= Window->W) return;
+ if(Y >= Window->H) return;
+ if(X + W > Window->W) W = Window->W - X;
+ if(Y + H > Window->H) H = Window->H - Y;
+
+ // Render to buffer
+ // Create if needed?
+
UNIMPLEMENTED();
}
return ret;
}
-tHWND AxWin3_CreateWindow(tHWND Parent, const char *Renderer, int Flags, int DataBytes, void **DataPtr)
+tWindow *AxWin3_int_AllocateWindowInfo(int DataBytes, int *WinID)
+{
+ int idx, newWinID;
+ tWindowBlock *block, *prev;
+ tWindow *ret;
+
+ block = &gAxWin3_WindowList;
+ newWinID = giAxWin3_LowestFreeWinID;
+ for( idx = 0; block; newWinID ++ )
+ {
+ if( block->Windows[idx] == NULL )
+ break;
+ idx ++;
+ if(idx == WINDOWS_PER_ALLOC) {
+ prev = block;
+ block = block->Next;
+ idx = 0;
+ }
+ }
+
+ if( !block )
+ {
+ block = calloc(sizeof(tWindowBlock), 1);
+ prev->Next = block;
+ idx = 0;
+ }
+
+ ret = block->Windows[idx] = AxWin3_int_CreateWindowStruct(newWinID, DataBytes);
+ if(newWinID > giAxWin3_HighestUsedWinID)
+ giAxWin3_HighestUsedWinID = newWinID;
+ if(newWinID == giAxWin3_LowestFreeWinID)
+ giAxWin3_HighestUsedWinID ++;
+
+ if(WinID) *WinID = newWinID;
+
+ return ret;
+}
+
+tHWND AxWin3_CreateWindow(
+ tHWND Parent, const char *Renderer, int Flags,
+ int DataBytes, void **DataPtr,
+ tAxWin3_WindowMessageHandler MessageHandler
+ )
{
tWindow *ret;
int newWinID;
tAxWin_IPCMessage *msg;
tIPCMsg_CreateWin *create_win;
- // TODO: Validate `Parent`
-
// Allocate a window ID
- {
- int idx;
- tWindowBlock *block, *prev;
- block = &gAxWin3_WindowList;
- newWinID = giAxWin3_LowestFreeWinID;
- for( idx = 0; block; newWinID ++ )
- {
- if( block->Windows[idx] == NULL )
- break;
- idx ++;
- if(idx == WINDOWS_PER_ALLOC) {
- prev = block;
- block = block->Next;
- idx = 0;
- }
- }
-
- if( !block )
- {
- block = calloc(sizeof(tWindowBlock), 1);
- prev->Next = block;
- idx = 0;
- }
-
- ret = block->Windows[idx] = AxWin3_int_CreateWindowStruct(newWinID, DataBytes);
-
- if(newWinID > giAxWin3_HighestUsedWinID)
- giAxWin3_HighestUsedWinID = newWinID;
- if(newWinID == giAxWin3_LowestFreeWinID)
- giAxWin3_HighestUsedWinID ++;
- }
+ ret = AxWin3_int_AllocateWindowInfo(DataBytes, &newWinID);
+ if(!ret) return NULL;
+ ret->Handler = MessageHandler;
// Create message
msg = AxWin3_int_AllocateIPCMessage(Parent, IPCMSG_CREATEWIN, 0, dataSize);
AxWin3_int_SendIPCMessage(msg);
free(msg);
- // TODO: Detect errors in AxWin3_CreateWindow
+ // TODO: Detect and handle possible errors
// Return success
if(DataPtr) *DataPtr = ret->Data;
void AxWin3_DestroyWindow(tHWND Window)
{
+ tAxWin_IPCMessage *msg;
+
+ msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_DESTROYWIN, 0, 0);
+ AxWin3_int_SendIPCMessage(msg);
+ free(msg);
+}
+
+void AxWin3_ShowWindow(tHWND Window, int bShow)
+{
+ tAxWin_IPCMessage *msg;
+ tIPCMsg_ShowWindow *info;
+
+ msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_SHOWWINDOW, 0, sizeof(*info));
+ info = (void*)msg->Data;
+ info->bShow = !!bShow;
+
+ AxWin3_int_SendIPCMessage(msg);
+
+ free(msg);
+}
+
+void AxWin3_SetWindowPos(tHWND Window, short X, short Y, short W, short H)
+{
+ tAxWin_IPCMessage *msg;
+ tIPCMsg_SetWindowPos *info;
+
+ msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_SETWINPOS, 0, sizeof(*info));
+ info = (void*)msg->Data;
+
+ info->Fields = 0xF;
+ info->X = X; info->Y = Y;
+ info->W = W; info->H = H;
+
+ AxWin3_int_SendIPCMessage(msg);
+ free(msg);
+}
+
+void AxWin3_MoveWindow(tHWND Window, short X, short Y)
+{
+ tAxWin_IPCMessage *msg;
+ tIPCMsg_SetWindowPos *info;
+
+ msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_SETWINPOS, 0, sizeof(*info));
+ info = (void*)msg->Data;
+
+ info->Fields = 0x3;
+ info->X = X;
+ info->Y = Y;
+
+ AxWin3_int_SendIPCMessage(msg);
+
+ free(msg);
+}
+
+void AxWin3_ResizeWindow(tHWND Window, short W, short H)
+{
+ tAxWin_IPCMessage *msg;
+ tIPCMsg_SetWindowPos *info;
+
+ msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_SETWINPOS, 0, sizeof(*info));
+ info = (void*)msg->Data;
+
+ info->Fields = 0xC;
+ info->W = W;
+ info->H = H;
+
+ AxWin3_int_SendIPCMessage(msg);
+
+ free(msg);
}
+
extern tAxWin3_MessageCallback AxWin3_SetMessageCallback(tAxWin3_MessageCallback Callback);
extern void AxWin3_MainLoop(void);
-extern tHWND AxWin3_CreateWindow(tHWND Parent, const char *Renderer, int Flags, int DataBytes, void **DataPtr);
+extern tHWND AxWin3_CreateWindow(tHWND Parent, const char *Renderer, int Flags, int DataBytes, void **DataPtr,
+ tAxWin3_WindowMessageHandler MessageHandler);
extern void AxWin3_DestroyWindow(tHWND Window);
extern void AxWin3_SendMessage(tHWND Window, int Length, void *Data);
-extern void AxWin3_SetWindowPos(tHWND Window, int X, int Y, int W, int H);
-extern void AxWin3_SetWindowShown(tHWND Window, int bShow);
+extern void AxWin3_ShowWindow(tHWND Window, int bShow);
+extern void AxWin3_SetWindowPos(tHWND Window, short X, short Y, short W, short H);
+extern void AxWin3_MoveWindow(tHWND Window, short X, short Y);
+extern void AxWin3_ResizeWindow(tHWND Window, short W, short H);
#endif