void create_sidebar(void);
void create_mainmenu(void);
void create_run_dialog(void);
+void mainmenu_run_dialog(void *unused);
// === GLOBALS ===
tHWND gSidebar;
create_mainmenu();
create_run_dialog();
+ AxWin3_RegisterAction(gSidebar, "Interface>Run", (tAxWin3_HotkeyCallback)mainmenu_run_dialog);
+// AxWin3_RegisterAction(gSidebar, "Interface>Terminal", mainmenu_app_terminal);
+// AxWin3_RegisterAction(gSidebar, "Interface>TextEdit", mainmenu_app_textedit);
+
// Idle loop
AxWin3_MainLoop();
// --------------------------------------------------------------------
int run_dorun(tAxWin3_Widget *unused)
{
+ _SysDebug("DoRun pressed");
char *cmd = AxWin3_Widget_GetText(gRunInput);
_SysDebug("Command string '%s'", cmd);
AxWin3_ShowWindow(gRunDialog, 0);
extern void WM_Hotkey_Register(int nKeys, uint32_t *Keys, const char *ActionName);
+extern void WM_Hotkey_RegisterAction(const char *ActionName, tWindow *Target, uint16_t Index);
extern void WM_Hotkey_KeyDown(uint32_t Scancode);
extern void WM_Hotkey_KeyUp(uint32_t Scancode);
#include <stdio.h>
#include <wm.h>
#include <wm_internals.h>
+#include <wm_hotkeys.h>
#define AXWIN_PORT 4101
int IPC_Msg_RegisterAction(tIPC_Client *Client, tAxWin_IPCMessage *Msg)
{
+ tIPCMsg_RegAction *info = (void*)Msg->Data;
+ tWindow *win;
+
ASSERT(Msg->ID == IPCMSG_REGACTION);
+
+ if( Msg->Size < sizeof(*info) + 1 )
+ return -1;
+
+ win = IPC_int_GetWindow(Client, Msg->Window);
+ if(!win) return 1;
+
+ if( strnlen(info->Action, Msg->Size - sizeof(*info)) == Msg->Size - sizeof(*info) )
+ return 1;
+
+ _SysDebug("RegisterAction %p:%i [%i]\"%s\"",
+ Client, Msg->Window, info->Index, info->Action
+ );
+
+ WM_Hotkey_RegisterAction(info->Action, win, info->Index);
+
return 0;
}
#include <acess/sys.h>
#include <stdlib.h>
#include <stdio.h>
+#include <axwin3/keysyms.h>
// === IMPORTS ===
extern void Video_Setup(void);
extern int Renderer_Background_Init(void);
extern int Renderer_Framebuffer_Init(void);
extern void WM_Update(void);
+extern void WM_Hotkey_Register(int nKeys, uint32_t *Keys, const char *ActionName);
// === PROTOTYPES ===
void ParseCommandline(int argc, char **argv);
Renderer_Background_Init();
Renderer_Framebuffer_Init();
WM_Initialise();
+
+ // TODO: Config
+ uint32_t keys[4];
+ keys[0] = KEYSYM_LEFTGUI; keys[1] = KEYSYM_r;
+ WM_Hotkey_Register(2, keys, "Interface>Run");
// Spawn interface root
if( clone(CLONE_VM, 0) == 0 )
// }
}
+int Widget_GetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg)
+{
+ if( Len < sizeof(*Msg) )
+ return 0;
+ if( Len > sizeof(*Msg) )
+ return 1; // Pass to user
+
+ const char *text = NULL;
+ tElement *ele = Widget_GetElementById(Info, Msg->WidgetID);
+ if(ele)
+ text = ele->Text;
+
+ char buf[sizeof(tWidgetMsg_SetText) + strlen(text?text:"") + 1];
+ tWidgetMsg_SetText *omsg = (void*)buf;
+
+ if( text ) {
+ omsg->WidgetID = Msg->WidgetID;
+ strcpy(omsg->Text, text);
+ }
+ else {
+ omsg->WidgetID = -1;
+ omsg->Text[0] = 0;
+ }
+
+ WM_SendMessage(Info->RootElement.Window, Info->RootElement.Window, MSG_WIDGET_GETTEXT, sizeof(buf), buf);
+ return 0;
+}
+
int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data)
{
tWidgetWin *info = Target->RendererInfo;
case MSG_WIDGET_SETTEXT:
Widget_SetText(info, Len, Data);
return 0;
+ case MSG_WIDGET_GETTEXT:
+ return Widget_GetText(info, Len, Data);
//
default:
h->Target = (void*)( h->Keys + nKeys );
strcpy((char*)h->Target, ActionName);
memcpy(h->Keys, Keys, nKeys * sizeof(uint32_t));
+
+ h->Next = NULL;
+ if( gpWM_Hotkeys )
+ gpWM_Hotkeys->Next = h;
+ gpWM_Hotkeys = h;
}
void WM_Hotkey_RegisterAction(const char *ActionName, tWindow *Target, uint16_t Index)
{
_UnsetKey(Scancode);
+ // Ensure that hotkeys are triggered on the longest sequence
+ // (so Win-Shift-R doesn't trigger Win-R if shift is released)
if( !gbWM_HasBeenKeyDown )
return ;
if( _IsKeySet(hk->Keys[i]) ) continue ;
break;
}
- if( i == hk->nKeys )
+ _SysDebug("%i/%i satisfied for %s", i, hk->nKeys, hk->Target);
+ if( i != hk->nKeys )
continue ;
// Fire shortcut
void WM_Hotkey_FireEvent(const char *Target)
{
+ _SysDebug("WM_Hotkey_FireEvent: (%s)", Target);
// - Internal events (Alt-Tab, Close, Maximize, etc...)
// TODO: Internal event handling
static void _SetKey(uint32_t sc)
{
+ _SysDebug("_SetKey: (%x)", sc);
if( sc >= MAX_STATE_SCANCODE ) return;
gWM_KeyStates[sc/8] |= 1 << (sc % 8);
}
static void _UnsetKey(uint32_t sc)
{
+ _SysDebug("_UnsetKey: (%x)", sc);
if( sc >= MAX_STATE_SCANCODE ) return;
gWM_KeyStates[sc/8] &= ~(1 << (sc % 8));
}
for(win = ret->FirstChild; win; win = win->NextSibling)
{
if( !(win->Flags & WINFLAG_SHOW) ) continue ;
- if( X < win->X || X >= win->X + win->W ) continue;
- if( Y < win->Y || Y >= win->Y + win->H ) continue;
+ if( X < win->X || X >= win->X + win->RealW ) continue;
+ if( Y < win->Y || Y >= win->Y + win->RealH ) continue;
next_win = win; // Overwrite as we want the final rendered window
}
}
typedef struct sIPCMsg_Boolean tIPCMsg_Boolean;
typedef struct sIPCMsg_SetWindowPos tIPCMsg_SetWindowPos;
typedef struct sIPCMsg_SendMsg tIPCMsg_SendMsg;
+typedef struct sIPCMsg_RegAction tIPCMsg_RegAction;
typedef struct sIPCMsg_GetDisplayDims tIPCMsg_GetDisplayDims;
typedef struct sIPCMsg_RetDisplayDims tIPCMsg_RetDisplayDims;
uint8_t bSetDims;
};
+struct sIPCMsg_RegAction
+{
+ uint16_t Index;
+ char Action[];
+};
+
struct sIPCMsg_GetDisplayDims
{
uint16_t DisplayID;
#include <axwin3/axwin.h>
#include <axwin3/widget.h>
#include "include/internal.h"
-#include "include/ipc.h"
#include <stdlib.h>
#include <widget_messages.h>
#include <string.h>
{
char buf[sizeof(tWidgetMsg_SetText)];
tWidgetMsg_SetText *msg = (void*)buf;
- tAxWin_IPCMessage *retmsg;
- char *ret;
+ size_t retmsg_size;
msg->WidgetID = Widget->ID;
AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_GETTEXT, sizeof(buf), buf);
- retmsg = AxWin3_int_WaitIPCMessage(MSG_WIDGET_GETTEXT);
- msg = (void*)retmsg->Data;
-
- if( retmsg->Size < sizeof(*msg) ) {
- free(retmsg);
+ msg = AxWin3_WaitMessage(Widget->Window, MSG_WIDGET_GETTEXT, &retmsg_size);
+ if( retmsg_size < sizeof(*msg) ) {
+ free(msg);
return NULL;
}
- ret = strndup(msg->Text, retmsg->Size - sizeof(*msg));
- free(retmsg);
+ char *ret = strndup(msg->Text, retmsg_size - sizeof(*msg));
+ free(msg);
return ret;
}
#include <string.h>
#include "include/internal.h"
#include "include/ipc.h"
+#include <wm_messages.h>
-#define WINDOWS_PER_ALLOC (63)
+#define WINDOWS_PER_ALLOC (64-1) // -1 to make it 64 pointers (+ Next)
+#define MAX_HOTKEYS 32
typedef struct sWindowBlock tWindowBlock;
int giAxWin3_LowestFreeWinID;
int giAxWin3_HighestUsedWinID;
tWindowBlock gAxWin3_WindowList;
+tAxWin3_HotkeyCallback gAxWin3_Hotkeys[MAX_HOTKEYS];
// === CODE ===
tWindow *AxWin3_int_CreateWindowStruct(uint32_t ServerID, int ExtraBytes)
return ;
}
_SysDebug("IPC Message 0x%x - %i bytes", info->ID, info->Length);
- dest->Handler(dest, info->ID, info->Length, info->Data);
+
+ if( dest->Handler(dest, info->ID, info->Length, info->Data) )
+ ;
+ else {
+ switch( info->ID )
+ {
+ case WNDMSG_HOTKEY: {
+ const struct sWndMsg_Hotkey *mi = (void*)info->Data;
+ if( mi->ID >= MAX_HOTKEYS )
+ ; // TODO: Error when hotkey is out of range
+ else if( gAxWin3_Hotkeys[mi->ID] == 0 )
+ _SysDebug("--- Unmapped hotkey ID %i fired", mi->ID);
+ else
+ gAxWin3_Hotkeys[mi->ID]();
+ }break;
+ default:
+ _SysDebug("--- Unhandled SENDMSG %i", info->ID);
+ break;
+ }
+ }
break; }
default:
_SysDebug("Unknow message ID %i", Msg->ID);
free(msg);
}
+void *AxWin3_WaitMessage(tHWND Window, int MessageID, size_t *Length)
+{
+ tAxWin_IPCMessage *msg;
+
+ for( ;; )
+ {
+ msg = AxWin3_int_WaitIPCMessage(IPCMSG_SENDMSG);
+ if( msg->Window != AxWin3_int_GetWindowID(Window) ) {
+ AxWin3_int_HandleMessage(msg);
+ continue ;
+ }
+ tIPCMsg_SendMsg *info = (void*)msg->Data;
+ if( info->ID != MessageID ) {
+ AxWin3_int_HandleMessage(msg);
+ continue ;
+ }
+
+ *Length = info->Length;
+ void *ret = malloc(info->Length);
+ memcpy(ret, info->Data, info->Length);
+ free(msg);
+
+ return ret;
+ }
+}
+
void AxWin3_FocusWindow(tHWND Window)
{
tAxWin_IPCMessage *msg;
free(msg);
}
+int AxWin3_RegisterAction(tHWND Window, const char *Action, tAxWin3_HotkeyCallback cb)
+{
+ int i;
+ for( i = 0; i < MAX_HOTKEYS; i ++ )
+ {
+ if( gAxWin3_Hotkeys[i] == NULL )
+ {
+ tAxWin_IPCMessage *msg;
+ struct sIPCMsg_RegAction *info;
+ gAxWin3_Hotkeys[i] = cb;
+
+ msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_REGACTION, 0, sizeof(*info)+strlen(Action)+1);
+ info = (void*)msg->Data;
+
+ info->Index = i;
+ strcpy(info->Action, Action);
+
+ AxWin3_int_SendIPCMessage(msg);
+ free(msg);
+ return i;
+ }
+ }
+ return -1;
+}
+
#ifndef _AXWIN3_AXWIN_H_
#define _AXWIN3_AXWIN_H_
+#include <stddef.h> // size_t
+
// === CONSTANTS ===
// === TYPES ===
typedef unsigned int tAxWin3_Colour; // TODO: Actual 32-bit
typedef void (*tAxWin3_MessageCallback)(int SourceTID, int Length);
+typedef void (*tAxWin3_HotkeyCallback)(void);
typedef int (*tAxWin3_WindowMessageHandler)(tHWND Window, int Message, int Length, void *Data);
* \param Window Handle to a window to destroy
*/
extern void AxWin3_DestroyWindow(tHWND Window);
+extern int AxWin3_RegisterAction(tHWND Window, const char *Action, tAxWin3_HotkeyCallback cb);
// --- Core window management functions
extern void AxWin3_SendMessage(tHWND Window, tHWND Dest, int Message, int Length, void *Data);
+extern void *AxWin3_WaitMessage(tHWND Window, int MessageID, size_t *Length);
extern void AxWin3_SetWindowTitle(tHWND Window, const char *Title);
extern void AxWin3_FocusWindow(tHWND Window);
extern void AxWin3_ShowWindow(tHWND Window, int bShow);