#define WINFLAG_SHOW 0x00000001
//! Window contents are valid
#define WINFLAG_CLEAN 0x00000002
+//! All child windows are un-changed
+#define WINFLAG_CHILDCLEAN 0x00000004
#define WINFLAG_RENDER_MASK 0x00FFFF00
#define WINFLAG_USR_MASK 0xFF000000
// === FUNCTIONS ===
// --- Management
extern tWindow *WM_CreateWindow(tWindow *Parent, int Flags, const char *Renderer);
+extern void WM_Invalidate(tWindow *Window);
extern void WM_ShowWindow(tWindow *Window, int bShow);
extern int WM_ResizeWindow(tWindow *Window, int W, int H);
extern int WM_MoveWindow(tWindow *Window, int X, int Y);
int IPC_Type_Sys_Compare(const void *Ident1, const void *Ident2)
{
- return *(const int*)Ident1 - *(const int*)Ident2;
+ return *(const tid_t*)Ident1 - *(const tid_t*)Ident2;
}
void IPC_Type_Sys_Send(const void *Ident, size_t Length, const void *Data)
tIPC_Client *IPC_int_GetClient(const tIPC_Type *IPCType, const void *Ident)
{
- int pos; // Position where the new client will be inserted
+ int pos = 0; // Position where the new client will be inserted
int ident_size;
tIPC_Client *ret;
// - Search list of registered clients
+ if(giIPC_ClientCount > 0)
{
tIPC_Client target;
int div;
{
div /= 2;
cmp = _CompareClientPtrs(&ret, &gIPC_Clients[pos]);
+// _SysDebug("Checking against %i gives %i", pos, cmp);
if(cmp == 0) break;
if(cmp < 0)
pos -= div;
// - Create a new client entry
ident_size = IPCType->GetIdentSize(Ident);
+// _SysDebug("ident_size = %i", ident_size);
ret = malloc( sizeof(tIPC_Client) + ident_size );
if(!ret) return NULL;
ret->IPCType = IPCType;
- ret->Ident = &ret + 1; // Get the end of the structure
+ ret->Ident = ret + 1; // Get the end of the structure
memcpy( (void*)ret->Ident, Ident, ident_size );
ret->nWindows = 0;
ret->Windows = NULL;
if( WindowID == -1 )
return NULL;
- if( WindowID >= Client->nWindows )
+ if( WindowID >= Client->nWindows ) {
+// _SysDebug("Window %i out of range for %p (%i)", WindowID, Client, Client->nWindows);
return NULL;
+ }
return Client->Windows[WindowID];
}
Client->nWindows = WindowID + 1;
Client->Windows = realloc(Client->Windows, Client->nWindows*sizeof(tWindow*));
memset( &Client->Windows[oldCount], 0, (Client->nWindows-oldCount)*sizeof(tWindow*) );
+ _SysDebug("Expanded %p's window list from %i to %i", Client, oldCount, Client->nWindows);
}
-
+
+ _SysDebug("Assigned %p to window %i for %p", WindowPtr, WindowID, Client);
Client->Windows[WindowID] = WindowPtr;
}
win = IPC_int_GetWindow(Client, Msg->Window);
if(!win) return 1;
+ _SysDebug("info = {..., bSetPos=%i,bSetDims=%i}", info->bSetPos, info->bSetDims);
+
if(info->bSetPos)
WM_MoveWindow(win, info->X, info->Y);
if(info->bSetDims)
void IPC_Handle(const tIPC_Type *IPCType, const void *Ident, size_t MsgLen, tAxWin_IPCMessage *Msg)
{
tIPC_Client *client;
+ int rv = 0;
_SysDebug("IPC_Handle: (IPCType=%p, Ident=%p, MsgLen=%i, Msg=%p)",
IPCType, Ident, MsgLen, Msg);
// --- Create window
case IPCMSG_CREATEWIN:
_SysDebug(" IPC_Handle: IPCMSG_CREATEWIN");
- IPC_Msg_CreateWin(client, Msg);
+ rv = IPC_Msg_CreateWin(client, Msg);
break;
// --- Show/Hide a window
case IPCMSG_SHOWWINDOW:
_SysDebug(" IPC_Handle: IPCMSG_SHOWWINDOW");
- IPC_Msg_ShowWindow(client, Msg);
+ rv = IPC_Msg_ShowWindow(client, Msg);
break;
// --- Move/Resize a window
case IPCMSG_SETWINPOS:
_SysDebug(" IPC_Handle: IPCMSG_SETWINPOS");
- IPC_Msg_SetWinPos(client, Msg);
+ rv = IPC_Msg_SetWinPos(client, Msg);
break;
// --- Unknown message
_SysDebug("WARNING: Unknown message %i (%p)", Msg->ID, IPCType);
break;
}
+ if(rv)
+ _SysDebug("IPC_Handle: rv = %i", rv);
}
short FixedWith; //!< Fixed lengthways Size attribute (height)
short FixedCross; //!< Fixed Cross Size attribute (width)
+ tColour BackgroundColour;
+
char *Text;
// -- Attributes maitained by the element code
tWindow *Renderer_Widget_Create(int Flags)
{
- // TODO: Add info
- return WM_CreateWindowStruct( sizeof(tWidgetWin) );
+ tWindow *ret;
+ tWidgetWin *info;
+ ret = WM_CreateWindowStruct( sizeof(tWidgetWin) );
+ info = ret->RendererInfo;
+
+ info->RootElement.BackgroundColour = 0xCCCCCC;
+
+ return ret;
}
void Renderer_Widget_Redraw(tWindow *Window)
{
+ tWidgetWin *info = Window->RendererInfo;
+ WM_Render_FilledRect(Window, info->RootElement.BackgroundColour, 0, 0, 0xFFF, 0xFFF);
}
// --- Render / Resize ---
_SysDebug("Video_Blit: (%p (%i, %i) %ix%i)", Source, DstX, DstY, W, H);
+ if( DstX >= giScreenWidth) return ;
+ if( DstY >= giScreenHeight) return ;
// TODO: Handle -ve X/Y by clipping
if( DstX < 0 || DstY < 0 ) return ;
// TODO: Handle out of bounds by clipping too
if( DstX + W > giScreenWidth ) return;
- if( DstY + H > giScreenHeight ) return;
+ if( DstY + H > giScreenHeight )
+ H = giScreenWidth - DstY;
if( W <= 0 || H <= 0 ) return;
if(renderer == NULL)
return NULL;
+ if(!Parent)
+ Parent = gpWM_RootWindow;
+
// - Call create window function
ret = renderer->CreateWindow(RendererArg);
ret->Parent = Parent;
ret->Renderer = renderer;
-
- if(!Parent)
- Parent = gpWM_RootWindow;
+ ret->Flags = WINFLAG_CLEAN; // Note, not acutally clean, but it makes invaidate work
// Append to parent
if(Parent)
Window->Flags |= WINFLAG_SHOW;
else
Window->Flags &= ~WINFLAG_SHOW;
+ WM_Invalidate(Window);
}
int WM_MoveWindow(tWindow *Window, int X, int Y)
if(Y >= giScreenHeight) Y = giScreenHeight - 1;
Window->X = X; Window->Y = Y;
-
+
+ WM_Invalidate(Window);
+
return 0;
}
if(Window->Y + H < 0) Window->Y = -H + 1;
Window->W = W; Window->H = H;
+
+ WM_Invalidate(Window);
return 0;
}
+void WM_Invalidate(tWindow *Window)
+{
+ // Don't invalidate twice (speedup)
+ if( !(Window->Flags & WINFLAG_CLEAN) ) return;
+
+ _SysDebug("Invalidating %p");
+
+ // Mark for re-render
+ Window->Flags &= ~WINFLAG_CLEAN;
+
+ // Mark up the tree that a child window has changed
+ while( (Window = Window->Parent) )
+ {
+ _SysDebug("Childclean removed from %p", Window);
+ Window->Flags &= ~WINFLAG_CHILDCLEAN;
+ }
+}
+
// --- Rendering / Update
void WM_int_UpdateWindow(tWindow *Window)
{
// Ignore hidden windows
if( !(Window->Flags & WINFLAG_SHOW) )
return ;
- // Ignore unchanged windows
- if( Window->Flags & WINFLAG_CLEAN )
- return;
-
+
// Render
- Window->Renderer->Redraw(Window);
+ if( !(Window->Flags & WINFLAG_CLEAN) )
+ {
+ Window->Renderer->Redraw(Window);
+ Window->Flags |= WINFLAG_CLEAN;
+ }
// Process children
- for( child = Window->FirstChild; child; child = child->NextSibling )
+ if( !(Window->Flags & WINFLAG_CHILDCLEAN) )
{
- WM_int_UpdateWindow(child);
+ for( child = Window->FirstChild; child; child = child->NextSibling )
+ {
+ WM_int_UpdateWindow(child);
+ }
+ Window->Flags |= WINFLAG_CHILDCLEAN;
}
- Window->Flags |= WINFLAG_CLEAN;
}
void WM_int_BlitWindow(tWindow *Window)
void WM_Update(void)
{
// Don't redraw if nothing has changed
- if( gpWM_RootWindow->Flags & WINFLAG_CLEAN )
+ if( (gpWM_RootWindow->Flags & WINFLAG_CHILDCLEAN) )
return ;
// - Iterate through visible windows, updating them as needed
#include <axwin3/axwin.h>
#include <axwin3/widget.h>
#include "include/internal.h"
+#include <stdlib.h>
// === STRUCTURES ===
struct sAxWin3_Widget
{
tHWND Window;
+ uint32_t ID;
tAxWin3_Widget_Callback Callback;
};
ret = AxWin3_CreateWindow(
Parent, "Widget", RootEleFlags,
- sizeof(*info), AxWin3_Widget_MessageHandler
+ sizeof(*info) + sizeof(tAxWin3_Widget), AxWin3_Widget_MessageHandler
);
info = AxWin3_int_GetDataPtr(ret);
+
+ info->nElements = 1;
+ info->Elements = malloc(sizeof(tAxWin3_Widget*));
+ info->Elements[0] = (void*)(info + 1); // Get end of *info
+
+ AxWin3_ResizeWindow(ret, W, H);
return ret;
}
+void AxWin3_Widget_DestroyWindow(tHWND Window)
+{
+ // Free all element structures
+
+ // Free array
+
+ // Request window to be destroyed (will clean up any data stored in tHWND)
+}
+
+tAxWin3_Widget *AxWin3_Widget_GetRoot(tHWND Window)
+{
+ tWidgetWindowInfo *info = AxWin3_int_GetDataPtr(Window);
+ return info->Elements[0];
+}
+
+tAxWin3_Widget *AxWin3_Widget_AddWidget(tAxWin3_Widget *Parent, int Type, int Flags, const char *DebugName)
+{
+ // Assign ID
+
+ return NULL;
+}
extern tHWND AxWin3_Widget_CreateWindow(tHWND Parent, int W, int H, int RootEleFlags);
extern void AxWin3_Widget_DestroyWindow(tHWND Window);
-extern tAxWin3_Widget *AxWin3_WidgeT_GetRoot(tHWND Window);
+extern tAxWin3_Widget *AxWin3_Widget_GetRoot(tHWND Window);
extern tAxWin3_Widget *AxWin3_Widget_AddWidget(tAxWin3_Widget *Parent, int Type, int Flags, const char *DebugName);
extern void AxWin3_Widget_DelWidget(tAxWin3_Widget *Widget);