// WindowServer.cpp: implementation of the CWindowServer class.
//
//////////////////////////////////////////////////////////////////////
#include <string.h>
#include <stdio.h>
#include <os/os.h>
#include "WindowServer.h"
#include "Window.h"
#include "winframe.h"
#include "MsgQueue.h"
#include "ResFont.h"
#include "DesktopWnd.h"
#include "S3Graphics.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
extern "C" IWindowServer* OpenServer();
extern "C" const byte font1[], font2[];
extern ISurface* CreateGraphics(int nMode);
extern IFont* CreateFont(const byte* pFontData);
CWindow* desktop;
void __cdecl idle()
{
#if 0
msg_t msg;
IMsgQueue* queue;
HRESULT (*wndproc) (IWindow*, dword, dword);
queue = (IMsgQueue*) thrGetTls();
if (queue)
{
while (true)
{
if (SUCCEEDED(queue->GetMessage(&msg)))
{
/* Can't currently use IMsgQueue::DispatchMessage in kernel mode */
if (msg.wnd)
{
wndproc = (HRESULT (*) (IWindow*, dword, dword))
msg.wnd->GetAttrib(ATTR_WNDPROC);
if (wndproc)
wndproc(msg.wnd, msg.message, msg.params);
else
msg.wnd->DefWndProc(msg.message, msg.params);
}
}
}
}
#endif
}
CWindowServer::CWindowServer()
{
const word *font_dir, *ord;
const FontDirEntry *header;
windowdef_t def;
int i;
surface_t desc;
m_refs = 0;
m_gfx = CreateGraphics(0x13);
//m_gfx = new CS3Graphics;
m_gfx->GetSurfaceDesc(&desc);
memset(m_fonts, 0, sizeof(m_fonts));
m_fonts[0] = CreateFont(font2);
font_dir = (const word*) resFind(_info.base, RT_FONTDIR, 0, 0);
if (font_dir)
{
ord = font_dir + 1;
for (i = 0; i < *font_dir; i++)
{
header = (const FontDirEntry*) (ord + 1);
m_fonts[i + 1] = new CResFont(_info.base, *ord);
if (header->Version == 0x200)
ord = (const word*) ((const byte*) header + SIZEOF_FONTDIRENTRY20);
else
ord = (const word*) ((const byte*) header + sizeof(FontDirEntry));
}
}
DeviceOpen();
def.size = sizeof(def);
def.flags = WIN_X | WIN_Y | WIN_WIDTH | WIN_HEIGHT | WIN_PARENT;
def.x = def.y = 0;
def.width = desc.nWidth;
def.height = desc.nHeight;
def.parent = NULL;
AddRef();
desktop = new CDesktopWnd(&def, this);
desktop->UpdateWindow();
}
CWindowServer::~CWindowServer()
{
int i;
desktop->Release();
desktop = NULL;
for (i = 0; i < countof(m_fonts); i++)
if (m_fonts[i])
m_fonts[i]->Release();
m_gfx->Release();
}
HRESULT CWindowServer::QueryInterface(REFIID iid, void ** ppvObject)
{
if (InlineIsEqualGUID(iid, IID_IUnknown) ||
InlineIsEqualGUID(iid, IID_IDevice))
{
AddRef();
*ppvObject = (IDevice*) this;
return S_OK;
}
else if (InlineIsEqualGUID(iid, IID_IWindowServer))
{
AddRef();
*ppvObject = (IWindowServer*) this;
return S_OK;
}
else
return E_FAIL;
}
HRESULT CWindowServer::GetInfo(device_t* buf)
{
if (buf->size < sizeof(device_t))
return E_FAIL;
wcscpy(buf->name, L"Window Server");
return S_OK;
}
HRESULT CWindowServer::DeviceOpen()
{
if (thrGetInfo()->queue == NULL)
{
CMsgQueue* queue = new CMsgQueue;
//thrSetTls((dword) (IMsgQueue*) queue);
thrGetInfo()->queue = (dword) (IMsgQueue*) queue;
}
return S_OK;
}
IWindow* CWindowServer::CreateWindow(const windowdef_t* def)
{
CWindowFrame* frame;
CWindow* wnd;
windowdef_t deftemp = *def, def2 = *def;
rectangle_t rect;
AddRef();
deftemp.flags &= ~WIN_WNDPROC;
deftemp.wndproc = NULL;
frame = new CWindowFrame(&deftemp, this);
rect = *frame;
frame->AdjustForFrame(&rect);
def2.flags |= WIN_PARENT | WIN_X | WIN_Y | WIN_WIDTH | WIN_HEIGHT;
def2.parent = frame;
def2.x = rect.left;
def2.y = rect.top;
def2.width = rect.Width();
def2.height = rect.Height();
wnd = new CWindow(&def2, this);
frame->UpdateWindow();
return wnd;
}
ISurface* CWindowServer::GetScreen()
{
m_gfx->AddRef();
return m_gfx;
}
IFont* CWindowServer::GetFont(int index)
{
if (m_fonts[index])
{
m_fonts[index]->AddRef();
return m_fonts[index];
}
else
return NULL;
}