winamp/Src/Wasabi/api/wnd/wndapi.cpp
2024-09-24 14:54:57 +02:00

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;