LOCAL void fb_sendimessages(WINDISPLAY *mod, TBOOL do_interval) { struct TExecBase *TExecBase = TGetExecBase(mod); struct TNode *next, *node = mod->fbd_VisualList.tlh_Head; for (; (next = node->tln_Succ); node = next) { WINWINDOW *v = (WINWINDOW *) node; TIMSG *imsg; if (do_interval && (v->fbv_InputMask & TITYPE_INTERVAL) && fb_getimsg(mod, v, &imsg, TITYPE_INTERVAL)) TPutMsg(v->fbv_IMsgPort, TNULL, imsg); while ((imsg = (TIMSG *) TRemHead(&v->fbv_IMsgQueue))) TPutMsg(v->fbv_IMsgPort, TNULL, imsg); } }
static LRESULT CALLBACK win_wndproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { WINWINDOW *win = (WINWINDOW *) GetWindowLong(hwnd, GWL_USERDATA); WINDISPLAY *mod = win ? win->fbv_Display : TNULL; if (mod) { TIMSG *imsg; switch (uMsg) { default: TDBPRINTF(TDB_TRACE,("uMsg: %08x\n", uMsg)); break; case WM_CLOSE: if ((win->fbv_InputMask & TITYPE_CLOSE) && (fb_getimsg(mod, win, &imsg, TITYPE_CLOSE))) fb_sendimsg(mod, win, imsg); return 0; case WM_ERASEBKGND: return 0; case WM_GETMINMAXINFO: { LPMINMAXINFO mm = (LPMINMAXINFO) lParam; TINT m1, m2, m3, m4; win_getminmax(win, &m1, &m2, &m3, &m4, TTRUE); mm->ptMinTrackSize.x = m1; mm->ptMinTrackSize.y = m2; mm->ptMaxTrackSize.x = m3; mm->ptMaxTrackSize.y = m4; return 0; } case WM_PAINT: { PAINTSTRUCT ps; if (BeginPaint(win->fbv_HWnd, &ps)) { if ((win->fbv_InputMask & TITYPE_REFRESH) && (fb_getimsg(mod, win, &imsg, TITYPE_REFRESH))) { imsg->timsg_X = ps.rcPaint.left; imsg->timsg_Y = ps.rcPaint.top; imsg->timsg_Width = ps.rcPaint.right - ps.rcPaint.left; imsg->timsg_Height = ps.rcPaint.bottom - ps.rcPaint.top; TDBPRINTF(TDB_TRACE,("dirty: %d %d %d %d\n", imsg->timsg_X, imsg->timsg_Y, imsg->timsg_Width, imsg->timsg_Height)); fb_sendimsg(mod, win, imsg); } EndPaint(win->fbv_HWnd, &ps); } return 0; } case WM_ACTIVATE: #if 0 TDBPRINTF(TDB_INFO,("Window %p - Focus: %d\n", win, (LOWORD(wParam) != WA_INACTIVE))); if (!win->fbv_Borderless && (win->fbv_InputMask & TITYPE_FOCUS) && (fb_getimsg(mod, win, &imsg, TITYPE_FOCUS))) { imsg->timsg_Code = (LOWORD(wParam) != WA_INACTIVE); fb_sendimsg(mod, win, imsg); } #endif return 0; case WM_SIZE: win->fbv_Width = LOWORD(lParam); win->fbv_Height = HIWORD(lParam); if ((win->fbv_InputMask & TITYPE_NEWSIZE) && (fb_getimsg(mod, win, &imsg, TITYPE_NEWSIZE))) { imsg->timsg_Width = win->fbv_Width; imsg->timsg_Height = win->fbv_Height; fb_sendimsg(mod, win, imsg); } return 0; case WM_CAPTURECHANGED: TDBPRINTF(TDB_INFO,("Capture changed\n")); break; case WM_MOUSEMOVE: { TINT x = LOWORD(lParam); TINT y = HIWORD(lParam); win->fbv_MouseX = x; win->fbv_MouseY = y; if ((win->fbv_InputMask & TITYPE_MOUSEMOVE) && (fb_getimsg(mod, win, &imsg, TITYPE_MOUSEMOVE))) { imsg->timsg_MouseX = x; imsg->timsg_MouseY = y; fb_sendimsg(mod, win, imsg); } if (win->fbv_InputMask & TITYPE_MOUSEOVER) { POINT scrpos; GetCursorPos(&scrpos); // TDBPRINTF(20,("in window: %d\n", // (WindowFromPoint(scrpos) == win->fbv_HWnd))); #if 0 POINT scrpos; if (GetCapture() != win->fbv_HWnd) { SetCapture(win->fbv_HWnd); if (fb_getimsg(mod, win, &imsg, TITYPE_MOUSEOVER)) { imsg->timsg_Code = 1; TDBPRINTF(20,("Mouseover=true\n")); fb_sendimsg(mod, win, imsg); } } else { POINT scrpos; GetCursorPos(&scrpos); if ((WindowFromPoint(scrpos) != win->fbv_HWnd) || (x < 0) || (y < 0) || (x >= win->fbv_Width) || (y >= win->fbv_Height)) { ReleaseCapture(); if (fb_getimsg(mod, win, &imsg, TITYPE_MOUSEOVER)) { imsg->timsg_Code = 0; TDBPRINTF(20,("Mouseover=false\n")); fb_sendimsg(mod, win, imsg); } } } #endif } return 0; } case WM_LBUTTONDOWN: if ((win->fbv_InputMask & TITYPE_MOUSEBUTTON) && fb_getimsg(mod, win, &imsg, TITYPE_MOUSEBUTTON)) { imsg->timsg_Code = TMBCODE_LEFTDOWN; fb_sendimsg(mod, win, imsg); } return 0; case WM_LBUTTONUP: if ((win->fbv_InputMask & TITYPE_MOUSEBUTTON) && fb_getimsg(mod, win, &imsg, TITYPE_MOUSEBUTTON)) { imsg->timsg_Code = TMBCODE_LEFTUP; fb_sendimsg(mod, win, imsg); } return 0; case WM_RBUTTONDOWN: if ((win->fbv_InputMask & TITYPE_MOUSEBUTTON) && fb_getimsg(mod, win, &imsg, TITYPE_MOUSEBUTTON)) { imsg->timsg_Code = TMBCODE_RIGHTDOWN; fb_sendimsg(mod, win, imsg); } return 0; case WM_RBUTTONUP: if ((win->fbv_InputMask & TITYPE_MOUSEBUTTON) && fb_getimsg(mod, win, &imsg, TITYPE_MOUSEBUTTON)) { imsg->timsg_Code = TMBCODE_RIGHTUP; fb_sendimsg(mod, win, imsg); } return 0; case WM_MBUTTONDOWN: if ((win->fbv_InputMask & TITYPE_MOUSEBUTTON) && fb_getimsg(mod, win, &imsg, TITYPE_MOUSEBUTTON)) { imsg->timsg_Code = TMBCODE_MIDDLEDOWN; fb_sendimsg(mod, win, imsg); } return 0; case WM_MBUTTONUP: if ((win->fbv_InputMask & TITYPE_MOUSEBUTTON) && fb_getimsg(mod, win, &imsg, TITYPE_MOUSEBUTTON)) { imsg->timsg_Code = TMBCODE_MIDDLEUP; fb_sendimsg(mod, win, imsg); } return 0; case WM_SYSKEYDOWN: processkey(mod, win, TITYPE_KEYDOWN, 0); return 0; case WM_SYSKEYUP: processkey(mod, win, TITYPE_KEYUP, 0); return 0; case WM_KEYDOWN: processkey(mod, win, TITYPE_KEYDOWN, wParam); return 0; case WM_KEYUP: processkey(mod, win, TITYPE_KEYUP, wParam); return 0; case 0x020a: if (win->fbv_InputMask & TITYPE_MOUSEBUTTON) { TINT16 zdelta = (TINT16) HIWORD(wParam); if (zdelta != 0 && fb_getimsg(mod, win, &imsg, TITYPE_MOUSEBUTTON)) { imsg->timsg_Code = zdelta > 0 ? TMBCODE_WHEELUP : TMBCODE_WHEELDOWN; fb_sendimsg(mod, win, imsg); } } return 0; } } return DefWindowProc(hwnd, uMsg, wParam, lParam); }
static void processkey(WINDISPLAY *mod, WINWINDOW *win, TUINT type, TINT code) { TIMSG *imsg; TINT numchars = 0; WCHAR buff[2]; getqualifier(mod, win); switch (code) { case VK_LEFT: code = TKEYC_CRSRLEFT; break; case VK_UP: code = TKEYC_CRSRUP; break; case VK_RIGHT: code = TKEYC_CRSRRIGHT; break; case VK_DOWN: code = TKEYC_CRSRDOWN; break; case VK_ESCAPE: code = TKEYC_ESC; break; case VK_DELETE: code = TKEYC_DEL; break; case VK_BACK: code = TKEYC_BCKSPC; break; case VK_TAB: code = TKEYC_TAB; break; case VK_RETURN: code = TKEYC_RETURN; break; case VK_HELP: code = TKEYC_HELP; break; case VK_INSERT: code = TKEYC_INSERT; break; case VK_PRIOR: code = TKEYC_PAGEUP; break; case VK_NEXT: code = TKEYC_PAGEDOWN; break; case VK_HOME: code = TKEYC_POSONE; break; case VK_END: code = TKEYC_POSEND; break; case VK_PRINT: code = TKEYC_PRINT; break; case VK_SCROLL: code = TKEYC_SCROLL; break; case VK_PAUSE: code = TKEYC_PAUSE; break; case VK_DECIMAL: code = '.'; imsg->timsg_Qualifier |= TKEYQ_NUMBLOCK; break; case VK_ADD: code = '+'; imsg->timsg_Qualifier |= TKEYQ_NUMBLOCK; break; case VK_SUBTRACT: code = '-'; imsg->timsg_Qualifier |= TKEYQ_NUMBLOCK; break; case VK_MULTIPLY: code = '*'; imsg->timsg_Qualifier |= TKEYQ_NUMBLOCK; break; case VK_DIVIDE: code = '/'; imsg->timsg_Qualifier |= TKEYQ_NUMBLOCK; break; case VK_F1: case VK_F2: case VK_F3: case VK_F4: case VK_F5: case VK_F6: case VK_F7: case VK_F8: case VK_F9: case VK_F10: case VK_F11: case VK_F12: code = (TUINT) (code - VK_F1) + TKEYC_F1; break; default: numchars = ToUnicode(code, 0, win->fbv_KeyState, buff, 2, 0); if (numchars > 0) code = buff[0]; } if ((win->fbv_InputMask & type) && fb_getimsg(mod, win, &imsg, type)) { ptrdiff_t len; imsg->timsg_Code = code; len = (ptrdiff_t) encodeutf8(imsg->timsg_KeyCode, imsg->timsg_Code) - (ptrdiff_t) imsg->timsg_KeyCode; imsg->timsg_KeyCode[len] = 0; fb_sendimsg(mod, win, imsg); } }
LOCAL void fb_openwindow(WINDISPLAY *mod, struct TVRequest *req) { struct TExecBase *TExecBase = TGetExecBase(mod); TTAGITEM *tags = req->tvr_Op.OpenWindow.Tags; WINWINDOW *win; req->tvr_Op.OpenWindow.Window = TNULL; for (;;) { RECT wrect; BITMAPINFOHEADER *bmi; TUINT style; TUINT exstyle; TIMSG *imsg; const char *classname; TSTRPTR title; win = TAlloc0(mod->fbd_MemMgr, sizeof(WINWINDOW)); if (win == TNULL) break; TInitList(&win->penlist); InitializeCriticalSection(&win->fbv_LockExtents); win->fbv_Width = (TUINT) TGetTag(tags, TVisual_Width, FB_DEF_WIDTH); win->fbv_Height = (TUINT) TGetTag(tags, TVisual_Height, FB_DEF_HEIGHT); win->fbv_Left = (TUINT) TGetTag(tags, TVisual_WinLeft, 0xffffffff); win->fbv_Top = (TUINT) TGetTag(tags, TVisual_WinTop, 0xffffffff); win->fbv_Title = (TSTRPTR) TGetTag(tags, TVisual_Title, (TTAG) "TEKlib Visual"); win->fbv_Borderless = TGetTag(tags, TVisual_Borderless, TFALSE); win->fbv_UserData = TGetTag(tags, TVisual_UserData, TNULL); win->fbv_MinWidth = (TINT) TGetTag(tags, TVisual_MinWidth, (TTAG) -1); win->fbv_MinHeight = (TINT) TGetTag(tags, TVisual_MinHeight, (TTAG) -1); win->fbv_MaxWidth = (TINT) TGetTag(tags, TVisual_MaxWidth, (TTAG) -1); win->fbv_MaxHeight = (TINT) TGetTag(tags, TVisual_MaxHeight, (TTAG) -1); if (win->fbv_Borderless) { style = (WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS) & ~WS_BORDER; classname = FB_DISPLAY_CLASSNAME_POPUP; title = NULL; exstyle = WS_EX_TOPMOST | WS_EX_TOOLWINDOW; } else { style = WS_OVERLAPPEDWINDOW; classname = FB_DISPLAY_CLASSNAME; title = win->fbv_Title; exstyle = 0; } wrect.left = wrect.right = wrect.top = wrect.bottom = 0; AdjustWindowRectEx(&wrect, style, FALSE, exstyle); win->fbv_BorderWidth = wrect.right - wrect.left; win->fbv_BorderHeight = wrect.bottom - wrect.top; win->fbv_BorderLeft = -wrect.left; win->fbv_BorderTop = -wrect.top; if (!win->fbv_Borderless) { TINT m1, m2, m3, m4; win_getminmax(win, &m1, &m2, &m3, &m4, TTRUE); win->fbv_Width = TCLAMP(m1, (TINT) win->fbv_Width, m3); win->fbv_Height = TCLAMP(m2, (TINT) win->fbv_Height, m4); } if (win->fbv_Left != 0xffffffff && win->fbv_Top != 0xffffffff) { wrect.left = win->fbv_Left; wrect.top = win->fbv_Top; wrect.right = win->fbv_Left + win->fbv_Width; wrect.bottom = win->fbv_Top + win->fbv_Height; if (!AdjustWindowRectEx(&wrect, style, FALSE, exstyle)) break; win->fbv_Left = wrect.left; win->fbv_Top = wrect.top; win->fbv_HWnd = CreateWindowEx(exstyle, classname, title, style, win->fbv_Left, win->fbv_Top, wrect.right - wrect.left - win->fbv_BorderWidth, wrect.bottom - wrect.top - win->fbv_BorderHeight, (HWND) NULL, (HMENU) NULL, mod->fbd_HInst, (LPVOID) NULL); } else { win->fbv_HWnd = CreateWindowEx(exstyle, classname, title, style, CW_USEDEFAULT, CW_USEDEFAULT, win->fbv_Width, win->fbv_Height, (HWND) NULL, (HMENU) NULL, mod->fbd_HInst, (LPVOID) NULL); } if (win->fbv_HWnd == TNULL) break; GetWindowRect(win->fbv_HWnd, &wrect); win->fbv_Left = wrect.left + win->fbv_BorderLeft; win->fbv_Top = wrect.top + win->fbv_BorderHeight; win->fbv_Width = wrect.right - wrect.left - win->fbv_BorderWidth; win->fbv_Height = wrect.bottom - wrect.top - win->fbv_BorderHeight; SetWindowLongPtr(win->fbv_HWnd, GWLP_USERDATA, (LONG_PTR) win); win->fbv_HDC = GetDC(win->fbv_HWnd); win->fbv_Display = mod; win->fbv_InputMask = (TUINT) TGetTag(tags, TVisual_EventMask, 0); win->fbv_IMsgPort = req->tvr_Op.OpenWindow.IMsgPort; bmi = &win->fbv_DrawBitMap; bmi->biSize = sizeof(BITMAPINFOHEADER); bmi->biPlanes = 1; bmi->biBitCount = 32; bmi->biCompression = BI_RGB; bmi->biSizeImage = 0; bmi->biXPelsPerMeter = 1; bmi->biYPelsPerMeter = 1; bmi->biClrUsed = 0; bmi->biClrImportant = 0; TInitList(&win->fbv_IMsgQueue); req->tvr_Op.OpenWindow.Window = win; /* init default font */ win->fbv_CurrentFont = mod->fbd_FontManager.deffont; mod->fbd_FontManager.defref++; if (win->fbv_InputMask & TITYPE_INTERVAL) ++mod->fbd_NumInterval; /* register default font */ /*TDBPRINTF(TDB_TRACE,("Add window: %p\n", win->window));*/ /* add window on top of window stack: */ TAddHead(&mod->fbd_VisualList, &win->fbv_Node); SetBkMode(win->fbv_HDC, TRANSPARENT); ShowWindow(win->fbv_HWnd, SW_SHOWNORMAL); UpdateWindow(win->fbv_HWnd); if ((win->fbv_InputMask & TITYPE_FOCUS) && (fb_getimsg(mod, win, &imsg, TITYPE_FOCUS))) { imsg->timsg_Code = 1; TAddTail(&win->fbv_IMsgQueue, &imsg->timsg_Node); } if ((win->fbv_InputMask & TITYPE_REFRESH) && (fb_getimsg(mod, win, &imsg, TITYPE_REFRESH))) { imsg->timsg_X = 0; imsg->timsg_Y = 0; imsg->timsg_Width = win->fbv_Width; imsg->timsg_Height = win->fbv_Height; TAddTail(&win->fbv_IMsgQueue, &imsg->timsg_Node); } return; } TDBPRINTF(TDB_ERROR,("Window open failed\n")); fb_closeall(mod, win, TFALSE); }