/*
+ * Acess2 GUI v4
+ * - By John Hodge (thePowersGang)
+ *
+ * ipc.cpp
+ * - Client-Server communication (dispatch)
*/
#define __STDC_LIMIT_MACROS
#include <ipc.hpp>
#include <assert.h>
};
#include <CIPCChannel_AcessIPCPipe.hpp>
+#include <draw_control.hpp>
namespace AxWin {
namespace IPC {
int FillSelect(fd_set& rfds)
{
int ret = 0;
- for( auto channel : glChannels )
+ for( const auto channel : glChannels )
{
- _SysDebug("IPC::FillSelect - channel=%p", channel);
+ assert(channel);
ret = ::std::max(ret, channel->FillSelect(rfds));
}
return ret;
void HandleSelect(const fd_set& rfds)
{
- for( auto channel : glChannels )
+ for( const auto channel : glChannels )
{
+ assert(channel);
channel->HandleSelect(rfds);
}
}
}
-void SendNotify_Dims(CClient& client, unsigned int NewW, unsigned int NewH)
+void SendMessage_NotifyDims(CClient& client, unsigned int NewW, unsigned int NewH)
{
- assert(!"TODO: CClient::SendNotify_Dims");
+ _SysDebug("TODO: CClient::SendNotify_Dims");
}
void HandleMessage_Nop(CClient& client, CDeserialiser& message)
{
+ // Do nothing
}
void HandleMessage_Reply(CClient& client, CDeserialiser& message)
{
reply.WriteU16( (w <= UINT16_MAX ? w : UINT16_MAX) );
reply.WriteU16( (h <= UINT16_MAX ? h : UINT16_MAX) );
break; }
+ case IPC_GLOBATTR_MAXAREA:
+ assert(!"TODO: IPC_GLOBATTR_MAXAREA");
+ break;
default:
throw IPC::CClientFailure("Bad global attribute ID");
}
{
uint16_t win_id = message.ReadU16();
uint16_t attr_id = message.ReadU16();
- _SysDebug("_SetWindowAttr: (%i, %i)", win_id, attr_id);
+ _SysDebug("_SetWindowAttr: (Win=%i, ID=%i)", win_id, attr_id);
CWindow* win = client.GetWindow(win_id);
if(!win) {
int16_t new_y = message.ReadS16();
win->Move(new_x, new_y);
break; }
+ case IPC_WINATTR_SHOW:
+ win->Show( message.ReadU8() != 0 );
+ break;
+ case IPC_WINATTR_FLAGS:
+ win->SetFlags( message.ReadU8() ); // TODO: U8? why so small?
+ break;
+ case IPC_WINATTR_TITLE:
+ assert(!"TODO: IPC_WINATTR_TITLE");
+ break;
default:
_SysDebug("HandleMessage_SetWindowAttr - Bad attr %u", attr_id);
throw IPC::CClientFailure("Bad window attr");
void HandleMessage_GetWindowBuffer(CClient& client, CDeserialiser& message)
{
- assert(!"TODO HandleMessage_GetWindowBuffer");
+ uint16_t win_id = message.ReadU16();
+ _SysDebug("_GetWindowBuffer: (%i)", win_id);
+
+ CWindow* win = client.GetWindow(win_id);
+ if(!win) {
+ throw IPC::CClientFailure("_PushData: Bad window");
+ }
+
+ uint64_t handle = win->m_surface.GetSHMHandle();
+
+ CSerialiser reply;
+ reply.WriteU8(IPCMSG_REPLY);
+ reply.WriteU8(IPCMSG_GETWINBUF);
+ reply.WriteU16(win_id);
+ reply.WriteU64(handle);
+ client.SendMessage(reply);
+}
+
+void HandleMessage_DamageRect(CClient& client, CDeserialiser& message)
+{
+ uint16_t winid = message.ReadU16();
+ uint16_t x = message.ReadU16();
+ uint16_t y = message.ReadU16();
+ uint16_t w = message.ReadU16();
+ uint16_t h = message.ReadU16();
+
+ _SysDebug("_DamageRect: (%i %i,%i %ix%i)", winid, x, y, w, h);
+
+ CWindow* win = client.GetWindow(winid);
+ if(!win) {
+ throw IPC::CClientFailure("_PushData: Bad window");
+ }
+
+ CRect area(x,y,w,h);
+
+ win->Repaint(area);
}
void HandleMessage_PushData(CClient& client, CDeserialiser& message)
{
- assert(!"TODO HandleMessage_PushData");
+ uint16_t win_id = message.ReadU16();
+ uint16_t x = message.ReadU16();
+ uint16_t y = message.ReadU16();
+ uint16_t w = message.ReadU16();
+ uint16_t h = message.ReadU16();
+ _SysDebug("_PushData: (%i, (%i,%i) %ix%i)", win_id, x, y, w, h);
+
+ CWindow* win = client.GetWindow(win_id);
+ if(!win) {
+ throw IPC::CClientFailure("_PushData: Bad window");
+ }
+
+ for( unsigned int row = 0; row < h; row ++ )
+ {
+ const ::std::vector<uint8_t> scanline_data = message.ReadBuffer();
+ if( scanline_data.size() != w * 4 ) {
+ _SysDebug("ERROR _PushData: Scanline buffer size mismatch (%i,%i)",
+ scanline_data.size(), w*4);
+ continue ;
+ }
+ win->DrawScanline(y+row, x, w, scanline_data.data());
+ }
}
void HandleMessage_Blit(CClient& client, CDeserialiser& message)
{
}
void HandleMessage_DrawCtl(CClient& client, CDeserialiser& message)
{
- assert(!"TODO HandleMessage_DrawCtl");
+ uint16_t win_id = message.ReadU16();
+ uint16_t x = message.ReadU16();
+ uint16_t y = message.ReadU16();
+ uint16_t w = message.ReadU16();
+ uint16_t h = message.ReadU16();
+ uint16_t ctrl_id = message.ReadU16();
+ uint16_t frame = message.ReadU16();
+ _SysDebug("_DrawCtl: (%i, (%i,%i) %ix%i Ctl%i frame?=0x%04x)", win_id, x, y, w, h, ctrl_id, frame);
+
+ CWindow* win = client.GetWindow(win_id);
+ if(!win) {
+ throw IPC::CClientFailure("_DrawCtl: Bad window");
+ }
+
+ const CControl* ctrl = CControl::GetByID(ctrl_id);
+ if(!ctrl) {
+ throw IPC::CClientFailure("_DrawCtl: Invalid control ID");
+ }
+
+ CRect area(x,y,w,h);
+ ctrl->Render(win->m_surface, area);
}
void HandleMessage_DrawText(CClient& client, CDeserialiser& message)
{
+ uint16_t win_id = message.ReadU16();
+ uint16_t x = message.ReadU16();
+ uint16_t y = message.ReadU16();
+ uint16_t w = message.ReadU16();
+ uint16_t h = message.ReadU16();
+ ::std::string str = message.ReadString();
+
assert(!"TODO HandleMessage_DrawText");
}
[IPCMSG_GETWINATTR] = &HandleMessage_GetWindowAttr,
[IPCMSG_SENDIPC] = &HandleMessage_SendIPC, // Use the GUI server for low-bandwith IPC
[IPCMSG_GETWINBUF] = &HandleMessage_GetWindowBuffer,
+ [IPCMSG_DAMAGERECT] = &HandleMessage_DamageRect,
[IPCMSG_PUSHDATA] = &HandleMessage_PushData, // to a window's buffer
[IPCMSG_BLIT] = &HandleMessage_Blit, // Copy data from one part of the window to another
[IPCMSG_DRAWCTL] = &HandleMessage_DrawCtl, // Draw a control
return ;
}
- _SysDebug("IPC::HandleMessage - command=%i", command);
(message_handlers[command])(client, message);
- _SysDebug("IPC::HandleMessage - Completed");
}
CClientFailure::CClientFailure(std::string&& what):