385 lines
9.4 KiB
C++
385 lines
9.4 KiB
C++
|
#include <precomp.h>
|
||
|
#include <api.h>
|
||
|
#include "wndapi.h"
|
||
|
#include <api/wnd/api_window.h>
|
||
|
#include <tataki/canvas/ifc_canvas.h>
|
||
|
|
||
|
#include <api/wnd/deactivatemgr.h>
|
||
|
#include <api/wnd/wndtrack.h>
|
||
|
|
||
|
#include <api/syscb/callbacks/consolecb.h>
|
||
|
#include <api/wnd/keyboard.h>
|
||
|
|
||
|
#ifdef WASABI_COMPILE_SKIN
|
||
|
// #include <api/skin/groupmgr.h>
|
||
|
#endif
|
||
|
|
||
|
#ifdef WASABI_COMPILE_PAINTSETS
|
||
|
#ifdef WASABI_COMPILE_IMGLDR
|
||
|
#include <api/wnd/paintset.h>
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#ifdef WASABI_COMPILE_SKIN
|
||
|
//#include <api/skin/skin.h>
|
||
|
#endif
|
||
|
#include <bfc/stack.h>
|
||
|
#include <tataki/region/region.h>
|
||
|
wnd_api *wndApi = NULL;
|
||
|
|
||
|
#ifndef ODS
|
||
|
#define ODS(msg1, msg2) __ODS(__LINE__, msg1, msg2, 0);
|
||
|
#endif
|
||
|
|
||
|
static Stack<ifc_window*> modal_wnd_stack;
|
||
|
|
||
|
static void __ODS(int line, wchar_t *message1, wchar_t *message2, int severity) {
|
||
|
StringPrintfW s(L"wndApi(%d): %s: %s\n", line, message1, message2);
|
||
|
#ifdef WIN32
|
||
|
DebugStringW(L"%s\n", s);
|
||
|
#endif
|
||
|
WASABI_API_SYSCB->syscb_issueCallback(SysCallback::CONSOLE, ConsoleCallback::DEBUGMESSAGE, severity, reinterpret_cast<intptr_t>(s.getValue()));
|
||
|
}
|
||
|
|
||
|
WndApi::WndApi()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
WndApi::~WndApi()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
void WndApi::main_setRootWnd(ifc_window *w) {
|
||
|
genericwnd = w;
|
||
|
}
|
||
|
|
||
|
ifc_window *WndApi::main_getRootWnd() {
|
||
|
return genericwnd;
|
||
|
}
|
||
|
|
||
|
ifc_window *WndApi::getModalWnd() {
|
||
|
if (!modal_wnd_stack.peek()) return NULL;
|
||
|
return modal_wnd_stack.top();
|
||
|
}
|
||
|
|
||
|
void WndApi::pushModalWnd(ifc_window *w) {
|
||
|
modal_wnd_stack.push(w);
|
||
|
}
|
||
|
|
||
|
void WndApi::popModalWnd(ifc_window *w) {
|
||
|
if (getModalWnd() != w) return;
|
||
|
modal_wnd_stack.pop();
|
||
|
}
|
||
|
/* TODO: Benski> move to api_wndmgr */
|
||
|
ifc_window *WndApi::rootWndFromPoint(POINT *pt) {
|
||
|
return WindowTracker::rootWndFromPoint(pt);
|
||
|
}
|
||
|
|
||
|
ifc_window *WndApi::rootWndFromOSHandle(OSWINDOWHANDLE wnd) {
|
||
|
return WindowTracker::rootWndFromHwnd(wnd);
|
||
|
}
|
||
|
|
||
|
void WndApi::registerRootWnd(ifc_window *wnd) {
|
||
|
WindowTracker::addRootWnd(wnd);
|
||
|
}
|
||
|
|
||
|
void WndApi::unregisterRootWnd(ifc_window *wnd) {
|
||
|
WindowTracker::removeRootWnd(wnd);
|
||
|
}
|
||
|
/* --- end TO MOVE ---*/
|
||
|
|
||
|
int WndApi::rootwndIsValid(ifc_window *wnd) {
|
||
|
return windowTracker->checkWindow(wnd);
|
||
|
}
|
||
|
void WndApi::hookKeyboard(ifc_window *hooker) {
|
||
|
Keyboard::hookKeyboard(hooker);
|
||
|
}
|
||
|
|
||
|
void WndApi::unhookKeyboard(ifc_window *hooker) {
|
||
|
Keyboard::unhookKeyboard(hooker);
|
||
|
}
|
||
|
|
||
|
void WndApi::kbdReset() {
|
||
|
Keyboard::reset();
|
||
|
}
|
||
|
|
||
|
// so when a key is pressed in a basewnd, it is first intercepted and sent to these functions to check if the system should handle it instead of the wnd...
|
||
|
|
||
|
int WndApi::interceptOnChar(unsigned int c) {
|
||
|
return Keyboard::interceptOnChar(c);
|
||
|
}
|
||
|
|
||
|
int WndApi::interceptOnKeyDown(int k) {
|
||
|
return Keyboard::interceptOnKeyDown(k);
|
||
|
}
|
||
|
|
||
|
int WndApi::interceptOnKeyUp(int k) {
|
||
|
return Keyboard::interceptOnKeyUp(k);
|
||
|
}
|
||
|
|
||
|
int WndApi::interceptOnSysKeyDown(int k, int kd) {
|
||
|
return Keyboard::interceptOnSysKeyDown(k, kd);
|
||
|
}
|
||
|
|
||
|
int WndApi::interceptOnSysKeyUp(int k, int kd) {
|
||
|
return Keyboard::interceptOnSysKeyUp(k, kd);
|
||
|
}
|
||
|
|
||
|
// ... if not, then it is sent to the wnd, and if the wnd doesn't need it, it is then forwarded to the system again, for default handling :
|
||
|
|
||
|
int WndApi::forwardOnChar(ifc_window *from, unsigned int c, int kd) {
|
||
|
return Keyboard::onForwardOnChar(from, c, kd);
|
||
|
}
|
||
|
|
||
|
int WndApi::forwardOnKeyDown(ifc_window *from, int k, int kd) {
|
||
|
return Keyboard::onForwardOnKeyDown(from, k, kd);
|
||
|
}
|
||
|
|
||
|
int WndApi::forwardOnKeyUp(ifc_window *from, int k, int kd) {
|
||
|
return Keyboard::onForwardOnKeyUp(from, k, kd);
|
||
|
}
|
||
|
|
||
|
int WndApi::forwardOnSysKeyDown(ifc_window *from, int k, int kd) {
|
||
|
return Keyboard::onForwardOnSysKeyDown(from, k, kd);
|
||
|
}
|
||
|
|
||
|
int WndApi::forwardOnSysKeyUp(ifc_window *from, int k, int kd) {
|
||
|
return Keyboard::onForwardOnSysKeyUp(from, k, kd);
|
||
|
}
|
||
|
|
||
|
int WndApi::forwardOnKillFocus() {
|
||
|
return Keyboard::onForwardOnKillFocus();
|
||
|
}
|
||
|
|
||
|
void WndApi::popupexit_register(PopupExitCallback *cb, ifc_window *watched)
|
||
|
{
|
||
|
popupExitChecker.registerCallback(cb, watched);
|
||
|
}
|
||
|
void WndApi::popupexit_deregister(PopupExitCallback *cb)
|
||
|
{
|
||
|
popupExitChecker.deregisterCallback(cb);
|
||
|
}
|
||
|
|
||
|
int WndApi::popupexit_check(ifc_window *w) {
|
||
|
|
||
|
return popupExitChecker.check(w);
|
||
|
}
|
||
|
|
||
|
void WndApi::popupexit_signal()
|
||
|
{
|
||
|
popupExitChecker.signal();
|
||
|
}
|
||
|
|
||
|
#define RenderBaseTexture renderBaseTexture //CUT
|
||
|
void WndApi::skin_renderBaseTexture(ifc_window *basetexturewnd, ifc_canvas *c, const RECT *r, ifc_window *destwnd, int alpha) {
|
||
|
if (c == NULL) {
|
||
|
ODS(L"illegal param", L"c == NULL");
|
||
|
return;
|
||
|
}
|
||
|
if (basetexturewnd == NULL) {
|
||
|
ODS(L"illegal param", L"base == NULL");
|
||
|
BaseCloneCanvas canvas(c);
|
||
|
canvas.fillRect(r, 0xFF00FF);
|
||
|
return;
|
||
|
}
|
||
|
if (destwnd == NULL) {
|
||
|
ODS(L"illegal param", L"destwnd == NULL");
|
||
|
return;
|
||
|
}
|
||
|
renderBaseTexture(basetexturewnd, c, *r, destwnd, alpha);
|
||
|
}
|
||
|
|
||
|
void WndApi::skin_registerBaseTextureWindow(ifc_window *window, const wchar_t *bitmap) {
|
||
|
if (window == NULL) {
|
||
|
ODS(L"illegal param", L"window == NULL");
|
||
|
return;
|
||
|
}
|
||
|
BaseTexture *s = new BaseTexture(window, bitmap);
|
||
|
baseTextureList.addItem(s);
|
||
|
}
|
||
|
|
||
|
void WndApi::skin_unregisterBaseTextureWindow(ifc_window *window) {
|
||
|
if (window == NULL) {
|
||
|
ODS(L"illegal param", L"window == NULL");
|
||
|
return;
|
||
|
}
|
||
|
for (int i=0;i<baseTextureList.getNumItems();i++) {
|
||
|
if (baseTextureList.enumItem(i)->getWnd() == window) {
|
||
|
BaseTexture *s = baseTextureList.enumItem(i);
|
||
|
baseTextureList.delByPos(i);
|
||
|
delete s;
|
||
|
if (baseTextureList.getNumItems() == 0)
|
||
|
baseTextureList.removeAll();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void WndApi::appdeactivation_push_disallow(ifc_window *from_whom) {
|
||
|
AppDeactivationMgr::push_disallow(from_whom);
|
||
|
}
|
||
|
|
||
|
void WndApi::appdeactivation_pop_disallow(ifc_window *from_whom) {
|
||
|
AppDeactivationMgr::pop_disallow(from_whom);
|
||
|
}
|
||
|
|
||
|
int WndApi::appdeactivation_isallowed(ifc_window *w) {
|
||
|
return AppDeactivationMgr::is_deactivation_allowed(w);
|
||
|
}
|
||
|
|
||
|
void WndApi::appdeactivation_setbypass(int i) {
|
||
|
AppDeactivationMgr::setbypass(i);
|
||
|
}
|
||
|
|
||
|
#ifdef WASABI_COMPILE_PAINTSETS
|
||
|
#ifdef WASABI_COMPILE_IMGLDR
|
||
|
|
||
|
void WndApi::paintset_render(int set, ifc_canvas *c, const RECT *r, int alpha) {
|
||
|
if (c == NULL) {
|
||
|
ODS(L"illegal param", L"c == NULL");
|
||
|
return;
|
||
|
}
|
||
|
if (r == NULL) {
|
||
|
ODS(L"illegal param", L"r == NULL");
|
||
|
return;
|
||
|
}
|
||
|
paintset_renderPaintSet(set, c, r, alpha);
|
||
|
}
|
||
|
|
||
|
#ifdef WASABI_COMPILE_FONTS
|
||
|
void WndApi::paintset_renderTitle(const wchar_t *t, ifc_canvas *c, const RECT *r, int alpha) {
|
||
|
if (c == NULL) {
|
||
|
ODS(L"illegal param", L"c == NULL");
|
||
|
return;
|
||
|
}
|
||
|
if (r == NULL) {
|
||
|
ODS(L"illegal param", L"r == NULL");
|
||
|
return;
|
||
|
}
|
||
|
::paintset_renderTitle(t, c, r, alpha);
|
||
|
}
|
||
|
#endif // WASABI_COMPILE_FONTS
|
||
|
#endif // WASABI_COMPILE_IMGLDR
|
||
|
#endif // WASABI_COMPILE_PAINTSETS
|
||
|
|
||
|
BaseTexture *WndApi::getBaseTexture(ifc_window *b) {
|
||
|
if (b == NULL) return NULL;
|
||
|
for (int i=0;i<baseTextureList.getNumItems();i++)
|
||
|
if (baseTextureList.enumItem(i)->getWnd() == b)
|
||
|
return baseTextureList.enumItem(i);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
void WndApi::renderBaseTexture(ifc_window *base, ifc_canvas *c, const RECT &r, ifc_window *dest, int alpha) {
|
||
|
renderBaseTexture(base, getBaseTexture(base), c, r, dest, alpha);
|
||
|
}
|
||
|
|
||
|
void WndApi::renderBaseTexture(ifc_window *base, BaseTexture *bt, ifc_canvas *c, const RECT &r, ifc_window *dest, int alpha) {
|
||
|
if (!bt) {
|
||
|
DebugString("Warning, no base texture found in renderBaseTexture\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
bt->renderBaseTexture(base, c, r, dest, alpha);
|
||
|
}
|
||
|
|
||
|
#ifndef SAFEROUND
|
||
|
#define SAFEROUND(d) ((float)(int)d == d) ? (int)d : (d - (float)(int)d > 0) ? ((int)d)+1 : ((int)d)-1
|
||
|
#endif
|
||
|
|
||
|
void BaseTexture::renderBaseTexture(ifc_window *wndbase, ifc_canvas *c, const RECT &r, ifc_window *dest, int alpha)
|
||
|
{
|
||
|
// pick our basetexture
|
||
|
AutoSkinBitmap *b = &texture;
|
||
|
|
||
|
if(!b) return;
|
||
|
|
||
|
// srcRect is the source rectangle in the basetexture
|
||
|
RECT srcRect;
|
||
|
// destProjectedRect is the basetexture rectangle projected to dest coordinates
|
||
|
RECT destProjectedRect;
|
||
|
|
||
|
ifc_window *p = dest;
|
||
|
POINT pt;
|
||
|
int sx=0, sy=0;
|
||
|
while (p && p != wndbase) {
|
||
|
if (!p->isVirtual()) {
|
||
|
p->getPosition(&pt);
|
||
|
sx += pt.x;
|
||
|
sy += pt.y;
|
||
|
}
|
||
|
p = p->getParent();
|
||
|
}
|
||
|
ASSERT(p);
|
||
|
|
||
|
wndbase->getNonClientRect(&destProjectedRect);
|
||
|
Wasabi::Std::offsetRect(&destProjectedRect, -sx, -sy);
|
||
|
|
||
|
Wasabi::Std::setRect(&srcRect, 0, 0, b->getWidth(), b->getHeight());
|
||
|
|
||
|
#if 0
|
||
|
// NONPORTABLE
|
||
|
HDC hdc=c->getHDC();
|
||
|
HRGN oldRgn=CreateRectRgn(0,0,0,0);
|
||
|
HRGN newRgn=CreateRectRgnIndirect(&r);
|
||
|
|
||
|
int cs=GetClipRgn(hdc,oldRgn);
|
||
|
|
||
|
ExtSelectClipRgn(hdc,newRgn,(cs!=1)?RGN_COPY:RGN_AND);
|
||
|
#endif
|
||
|
#ifdef _WIN32
|
||
|
// TODO: review: wtf does this even accomplish? we're still blitting to c at the end
|
||
|
BaseCloneCanvas clone(c);
|
||
|
RegionI oldRgn;
|
||
|
RegionI newRgn(&r);
|
||
|
|
||
|
int cs = clone.getClipRgn(&oldRgn);
|
||
|
|
||
|
if ( cs ) newRgn.andRegion(&oldRgn);
|
||
|
|
||
|
clone.selectClipRgn( &newRgn );
|
||
|
#endif
|
||
|
b->stretchToRectAlpha(c, &srcRect, &destProjectedRect, alpha);
|
||
|
|
||
|
#ifdef _WIN32
|
||
|
// TODO: review: wtf does this even accomplish? we're still blitting to c at the end
|
||
|
clone.selectClipRgn(cs ? &oldRgn : NULL);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
int WndApi::forwardOnMouseWheel(int l, int a) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
#ifdef WASABI_COMPILE_PAINTSETS
|
||
|
int WndApi::paintset_present(int set) {
|
||
|
return ::paintset_present(set);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
void WndApi::setDefaultDropTarget(void *dt) {
|
||
|
default_drop_target = dt;
|
||
|
}
|
||
|
|
||
|
void *WndApi::getDefaultDropTarget() {
|
||
|
return default_drop_target;
|
||
|
}
|
||
|
|
||
|
int WndApi::pushKeyboardLock() {
|
||
|
return ++kbdlock;
|
||
|
}
|
||
|
|
||
|
int WndApi::popKeyboardLock() {
|
||
|
return --kbdlock;
|
||
|
}
|
||
|
|
||
|
int WndApi::isKeyboardLocked() {
|
||
|
return kbdlock;
|
||
|
}
|
||
|
|
||
|
ifc_window *WndApi::genericwnd = NULL;
|
||
|
PtrList<BaseTexture> WndApi::baseTextureList;
|
||
|
void *WndApi::default_drop_target = NULL;
|
||
|
int WndApi::kbdlock = 0;
|