#include "wxinc.h" #include "wx/clipbrd.h" #include "wx/calctrl.h" #include "wx/colordlg.h" #include "wx/confbase.h" #include "wx/fileconf.h" #include "wx/fontdlg.h" #include "wx/fs_zip.h" #include "wx/image.h" #include #include #include "xvt.h" #include "statbar.h" #include "xvintern.h" #include "agasys.h" #include "fstrcmp.h" #include "matche.h" #ifdef WIN32 #include "oswin32.h" #include #else #include #include #include "oslinux.h" #include #include #endif #define CAST_WIN(win,w) XVT_ASSERT(win != NULL_WIN); wxWindow& w = *(wxWindow*)win #define CAST_TWIN(win,w) XVT_ASSERT(win != NULL_WIN); TwxWindow& w = *(TwxWindow*)win; XVT_ASSERT(_task_win != &w); #define CAST_TDC(win,dc) XVT_ASSERT(win != NULL_WIN); TDC& dc = GetTDCMapper().GetTDC(win); #define CAST_DC(win,dc) XVT_ASSERT(win != NULL_WIN); wxDC& dc = GetTDCMapper().GetDC(win); // Funzione interna di utilita' MENU_ITEM* xvt_menu_duplicate_tree(const MENU_ITEM* m); XVT_CONFIG* _config_ = NULL; wxWindow* _task_win = NULL; wxWindow* _mouse_trapper = NULL; RCT _startup_rect = { 0,0,0,0 }; wxString* _startup_dir = NULL; wxString _strDefaultStatbarText; static wxHashTable _nice_windows; static wxHashTable _nice_icons; static EVENT_HANDLER _task_win_handler = NULL; static XVT_ERRMSG_HANDLER _error_handler = NULL; #define XVT_ASSERT(test) assert_box((test), __LINE__, __FILE__ ) void assert_box(bool test, int line, const char * file) { if (!test) { bool display = (_error_handler == NULL) || (_error_handler(SEV_FATAL, NULL) == FALSE); if (display) { const wxString strMessage = wxString::Format("Sorry, the application passed some invalid parameters on line %d file %s.", line, file); const wxString strCaption = "Emulated XVT Error "; ::wxMessageBox(strMessage, strCaption, wxOK|wxICON_ERROR); } } } void xvt_sys_sorry_box(const char * file,int line) { static wxHashTable sorry; if (sorry.Get(line) == NULL) { sorry.Put(line, &sorry); // Dummy const wxString strMessage = wxString::Format("Function in file %s at line %d not implemented", file, line); ::wxMessageBox(strMessage); } } static bool RectIntersect(const wxRect &rect1, const wxRect &rect2) { if (rect1.GetRight() < rect2.GetLeft()) return false; if (rect2.GetRight() < rect1.GetLeft()) return false; if (rect1.GetBottom() < rect2.GetTop()) return false; if (rect2.GetBottom() < rect1.GetTop()) return false; return true; } wxRect NormalizeRCT(const RCT* prct) { XVT_ASSERT(prct != NULL); wxRect rct; rct.x = min(prct->left, prct->right); rct.y = min(prct->top, prct->bottom); rct.width = abs(prct->right - prct->left); rct.height = abs(prct->bottom - prct->top); return rct; } wxString GetResourceIni() { wxString strName; strName = *_startup_dir; strName += "/res/resource.ini"; return strName; } wxString GetResourceName(const char* type, int rid) { wxFileConfig ini("", "", GetResourceIni()); wxString strName = "/"; strName += type; strName += "s"; ini.SetPath(strName); wxString val; if (ini.Read(wxString::Format("%d", rid), &val)) { strName = *_startup_dir; strName += "/custom/"; strName += val; if (!wxFileExists(strName)) { strName = *_startup_dir; strName += "/res/"; strName += val; } } else strName.Empty(); return strName; } wxIcon* GetIconResource(int rid) { wxIcon* icon = (wxIcon*)_nice_icons.Get(rid); if (icon == NULL) { wxString strName = ::GetResourceName("Icon", rid); if (::wxFileExists(strName)) { icon = new wxIcon(strName, wxBITMAP_TYPE_ICO); _nice_icons.Put(rid, icon); } else icon = (wxIcon*)_nice_icons.Get(ICON_RSRC); } XVT_ASSERT(icon != NULL); return icon; } wxCursor* GetCursorResource(int rid) { static wxHashTable cursors; wxCursor* cursor = (wxCursor*)cursors.Get(rid); if (cursor == NULL) { switch (rid) { case CURSOR_CROSS: cursor = new wxCursor(wxCURSOR_CROSS); break; case CURSOR_IBEAM: cursor = new wxCursor(wxCURSOR_IBEAM); break; default: { wxString strName = ::GetResourceName("Cursor", rid); if (::wxFileExists(strName)) { #ifdef WIN32 cursor = new wxCursor(strName, wxBITMAP_TYPE_CUR); #else cursor = wxSTANDARD_CURSOR; #endif if (!cursor->Ok()) { delete cursor; cursor = NULL; } } } break; } if (cursor == NULL) { XVT_ASSERT(false); cursor = wxSTANDARD_CURSOR; } cursors.Put(rid, cursor); } return cursor; } /////////////////////////////////////////////////////////// // Caret emulation /////////////////////////////////////////////////////////// class TwxCaret : private wxTimer { WINDOW _owner; PNT _pos; wxSize _size; bool _visible; bool _drawn; protected: void Toggle(); virtual void Notify() { Toggle(); } public: void SetPos(int x, int y); void SetSize(int x, int y) { _size.x = x; _size.y = y; } void Show(WINDOW w, bool on = true); void Hide() { Show(NULL_WIN, false); } bool IsVisible() const { return _visible; } WINDOW Owner() const { return _owner; } void Kill(); TwxCaret() : _owner(NULL_WIN), _visible(false) { } virtual ~TwxCaret() { Kill(); } } _TheCaret; void TwxCaret::Kill() { _owner = NULL_WIN; } void TwxCaret::SetPos(int x, int y) { if (_visible && _drawn) // Lo cancella se necessario Toggle(); _pos.h = x; _pos.v = y; } void TwxCaret::Show(WINDOW w, bool on) { if (_visible && _drawn) Toggle(); // Lo cancella _visible = on; if (on) { _owner = w; Toggle(); wxTimer::Start(500); // Lampeggia ogni mezzo secondo } else { if (w == _owner || w == NULL_WIN) Kill(); } } void TwxCaret::Toggle() { if (!_visible || _owner == NULL_WIN) return; _drawn = !_drawn; DRAW_CTOOLS dct; xvt_dwin_get_draw_ctools(_owner, &dct); CPEN pen; pen.width = _size.x; pen.pat = PAT_SOLID; pen.style = P_SOLID; pen.color = dct.fore_color; xvt_dwin_set_draw_mode(_owner, M_NOT_XOR); xvt_dwin_set_cpen(_owner, &pen); xvt_dwin_draw_set_pos(_owner, _pos); PNT p = _pos; p.v -= _size.y-1; xvt_dwin_set_clip(_owner, NULL); // Non si sa mai! xvt_dwin_draw_line(_owner, p); xvt_dwin_set_draw_ctools(_owner, &dct); } /////////////////////////////////////////////////////////// // Generic Display context /////////////////////////////////////////////////////////// #define CAST_COLOR(xc, wc) wxColour wc((xc>>16)&0xFF, (xc>>8)&0xFF, xc&0xFF) #define MAKE_XVT_COLOR(wc) MAKE_COLOR(wc.Red(), wc.Green(), wc.Blue()) TDC::TDC(wxWindow* owner) : _dc(NULL) { _owner = owner; memset(&_dct, 0, sizeof(_dct)); _dct.pen.width = 0; _dct.pen.pat = PAT_SOLID; _dct.pen.style = P_SOLID; _dct.pen.color = COLOR_BLACK; _dct.brush.pat = PAT_HOLLOW; _dct.brush.color = COLOR_WHITE; _dct.mode = M_COPY; _dct.fore_color = COLOR_BLACK; _dct.back_color = COLOR_WHITE; _dct.opaque_text = FALSE; _font.SetPointSize(9); // Default font _deltaf = 0; SetClippingBox(NULL); // Reset clip area _dirty = -1; // Absolutely force setting } TDC::~TDC() { KillDC(); } void TDC::SetDirty(int d) { if (_dirty >= 0) _dirty = d; } static int PatternToStyle(PAT_STYLE pat) { int style = wxSOLID; switch (pat) { case PAT_NONE: case PAT_HOLLOW: style = wxTRANSPARENT; break; case PAT_SOLID: style = wxSOLID; break; case PAT_HORZ: style = wxHORIZONTAL_HATCH; break; case PAT_VERT: style = wxVERTICAL_HATCH; break; case PAT_FDIAG: style = wxFDIAGONAL_HATCH; break; case PAT_BDIAG: style = wxBDIAGONAL_HATCH; break; case PAT_CROSS: style = wxCROSS_HATCH; break; case PAT_DIAGCROSS: style = wxCROSSDIAG_HATCH; break; case PAT_RUBBER: case PAT_SPECIAL: default: SORRY_BOX(); break; } return style; } static int PenStyleToStyle(PEN_STYLE s, PAT_STYLE p) { int style = wxSOLID; if (p != PAT_HOLLOW) { switch (s) { case P_DOT : style = wxDOT; break; case P_DASH: style = wxSHORT_DASH; break; default: break; } } else style = wxTRANSPARENT; return style; } bool TDC::PenChanged() const { const int diff = memcmp(&_dct.pen, &_real_dct.pen, sizeof(_dct.pen)); return diff != 0; } bool TDC::BrushChanged() const { const int diff = memcmp(&_dct.brush, &_real_dct.brush, sizeof(_dct.brush)); return diff != 0; } bool TDC::FontChanged() const { return _font != _real_font; } #ifdef LINUX bool is_printer_dc(wxDC * dc) { return dc->IsKindOf(CLASSINFO(wxPostScriptDC)); } #endif wxDC& TDC::GetDC(bool bPaint) { if (bPaint) { KillDC(); _dc = new wxPaintDC(_owner); _dirty = -1; } else { if (_dc == NULL) { if (_owner == NULL || (unsigned long)_owner == SCREEN_WIN) _dc = new wxScreenDC(); else _dc = new wxClientDC(_owner); _dirty = -1; } } if (_dirty) { if (_dirty < 0 || PenChanged()) { CAST_COLOR(_dct.pen.color, pen_color); wxPen* pen = wxThePenList->FindOrCreatePen(pen_color, _dct.pen.width, PenStyleToStyle(_dct.pen.style, _dct.pen.pat)); _dc->SetPen(*pen); _real_dct.pen = _dct.pen; } if (_dirty < 0 || BrushChanged()) { CAST_COLOR(_dct.brush.color, brush_color); wxBrush* brush = wxTheBrushList->FindOrCreateBrush(brush_color, PatternToStyle(_dct.brush.pat)); _dc->SetBrush(*brush); _real_dct.brush = _dct.brush; } if (_dirty < 0 || _dct.mode != _real_dct.mode) { #ifdef LINUX if(!is_printer_dc(_dc)) { #endif switch(_dct.mode) { case M_COPY: _dc->SetLogicalFunction(wxCOPY); break; case M_OR: _dc->SetLogicalFunction(wxOR); break; case M_XOR: _dc->SetLogicalFunction(wxXOR); break; case M_CLEAR: _dc->SetLogicalFunction(wxCLEAR); break; case M_NOT_COPY: _dc->SetLogicalFunction(wxSRC_INVERT); break; case M_NOT_OR: _dc->SetLogicalFunction(wxNOR); break; case M_NOT_XOR: _dc->SetLogicalFunction(wxEQUIV); break; case M_NOT_CLEAR:_dc->SetLogicalFunction(wxSET); break; default: SORRY_BOX(); } #ifdef LINUX } #endif _real_dct.mode = _dct.mode; } if (_dirty < 0 || _dct.fore_color != _real_dct.fore_color) { CAST_COLOR(_dct.fore_color, fore_color); _dc->SetTextForeground(fore_color); _real_dct.fore_color = _dct.fore_color; } if (_dirty < 0 || _dct.back_color != _real_dct.back_color) { CAST_COLOR(_dct.back_color, back_color); _dc->SetTextBackground(back_color); _real_dct.back_color = _dct.back_color; } if (_dirty < 0 || _dct.opaque_text != _real_dct.opaque_text) { _dc->SetBackgroundMode(_dct.opaque_text ? wxSOLID : wxTRANSPARENT); _real_dct.opaque_text = _dct.opaque_text; } if (_dirty < 0 || FontChanged()) { _dc->SetFont(_font.Font(_dc, (WINDOW)_owner)); _real_font = _font; int height, desc, lead; _dc->GetTextExtent("Campo", NULL, &height, &desc, &lead); _deltaf = height-desc; } _dirty = false; } return *_dc; } void TDC::KillDC() { if (_dc != NULL) { SetClippingBox(NULL); delete _dc; _dc = NULL; } } void TDC::SetClippingBox(const RCT* pRct) { if (_dc != NULL) _dc->DestroyClippingRegion(); if (pRct) { const wxRect rct = NormalizeRCT(pRct); GetDC().SetClippingRegion(rct); _clip = *pRct; } else { _clip.left = _clip.top = 0; _clip.right = _clip.bottom = 32000; } } bool TDC::GetClippingBox(RCT* pRct) const { *pRct = _clip; return _clip.right > _clip.left; } WX_DECLARE_HASH_MAP(WINDOW, TDC*, wxIntegerHash, wxIntegerEqual, wxTDCHashMap); class TDCMapper : public wxTDCHashMap { WINDOW _pLastOwner; TDC* _pLastTDC; public: TDC& GetTDC(WINDOW owner); wxDC& GetDC(WINDOW owner, bool bPaint = false) { return GetTDC(owner).GetDC(bPaint); } void DestroyDC(WINDOW owner); void DestroyTDC(WINDOW owner); bool HasValidDC(WINDOW owner) const; TDCMapper() : _pLastOwner(NULL_WIN), _pLastTDC(NULL) { } virtual ~TDCMapper() { DestroyTDC(NULL_WIN); } }; TDCMapper& GetTDCMapper() { static TDCMapper* _dc_map = NULL; if (_dc_map == NULL) _dc_map = new TDCMapper; return *_dc_map; } void TDCMapper::DestroyDC(WINDOW owner) { if (owner) { TDC* pTDC = (*this)[owner]; if (pTDC) pTDC->KillDC(); } else { for (TDCMapper::iterator it = begin(); it != end(); ++it) { TDC* pTDC = it->second; if (pTDC) pTDC->KillDC(); } } } void TDCMapper::DestroyTDC(WINDOW owner) { if (owner != NULL_WIN) { TDC* pTDC = (*this)[owner]; if (pTDC) delete pTDC; erase(owner); } else { TDCMapper::iterator it; for (it = begin(); it != end(); ++it) { TDC* pTDC = it->second; if (pTDC) delete pTDC; } clear(); } _pLastOwner = NULL_WIN; } TDC& TDCMapper::GetTDC(WINDOW owner) { if (owner == _pLastOwner) return *_pLastTDC; TDC* pTDC = (*this)[owner]; if (pTDC == NULL) { if (owner == PRINTER_WIN) pTDC = new TPrintDC((wxWindow*)owner); else pTDC = new TDC((wxWindow*)owner); (*this)[owner] = pTDC; } _pLastOwner = owner; _pLastTDC = pTDC; return *pTDC; } bool TDCMapper::HasValidDC(WINDOW owner) const { if (owner == NULL_WIN) return false; if (owner == (WINDOW)_pLastOwner) return true; TDC* pTDC = (*((TDCMapper *) this))[owner]; return pTDC != NULL; } /////////////////////////////////////////////////////////// // Generic window class /////////////////////////////////////////////////////////// #define TIMER_ID 1 class TwxWindowBase : public wxWindow { #ifdef LINUX private: wxString m_strTitle; virtual void SetTitle(const wxString& title) { wxWindow::SetTitle(m_strTitle = title); } virtual wxString GetTitle() const { return m_strTitle; } #endif public: TwxWindowBase() { } TwxWindowBase(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint & pos, const wxSize & size, long style); DECLARE_DYNAMIC_CLASS(TwxWindowBase) }; IMPLEMENT_DYNAMIC_CLASS(TwxWindowBase, wxWindow) TwxWindowBase::TwxWindowBase(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &pos, const wxSize &size, long style) { #if wxCHECK_VERSION(2,6,1) // Evita inutili sfarfallamenti in quanto wxWidgets crea le finestre visibili per default wxWindowBase::Show(false); #endif Create(parent, id, pos, size, style, title); SetTitle(title); // Triste necessita', la Create sembra ignorare il titolo } class TwxWindow : public TwxWindowBase { private: MENU_ITEM* m_menu; protected: virtual void OnChar(wxKeyEvent& e); virtual void OnClose(wxCloseEvent& e); virtual void OnKeyDown(wxKeyEvent& e); virtual void OnKillFocus(wxFocusEvent& e); virtual void OnMenu(wxCommandEvent& event); virtual void OnMouseDouble(wxMouseEvent& e); virtual void OnMouseDown(wxMouseEvent& e); virtual void OnMouseMove(wxMouseEvent& e); virtual void OnMouseUp(wxMouseEvent& e); virtual void OnMouseWheel(wxMouseEvent& e); virtual void OnScroll(wxScrollEvent& e); virtual void OnScrollWin(wxScrollWinEvent& e); virtual void OnSetFocus(wxFocusEvent& e); virtual void OnSize(wxSizeEvent& e); virtual void OnTimer(wxTimerEvent& e); public: void DoXvtEvent(EVENT& e); virtual void OnPaint(wxPaintEvent& event); public: WIN_TYPE _type; EVENT_HANDLER _eh; long _app_data; wxTimer* _timer; void SetMenuTree(const MENU_ITEM* menu); MENU_ITEM* GetMenuTree() const { return m_menu; } TwxWindow() : m_menu(NULL), _type(W_DOC), _eh(NULL), _app_data(0L), _timer(NULL) { } TwxWindow(wxWindow *parent, wxWindowID id, const wxString& title, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0); virtual ~TwxWindow(); DECLARE_DYNAMIC_CLASS(TwxWindow); DECLARE_EVENT_TABLE(); }; class TTaskWin : public wxFrame { MENU_ITEM* m_menu; wxMenuBar* m_pOldBar; wxWindow* m_MenuOwner; protected: virtual void OnClose(wxCloseEvent& event); virtual void OnMenu(wxCommandEvent& event); virtual void OnSize(wxSizeEvent& event); public: virtual void OnPaint(wxPaintEvent& event); public: void SetMenuTree(const MENU_ITEM* tree); const MENU_ITEM* GetMenuTree() const { return m_menu; } void PushMenuTree(const MENU_ITEM* tree, wxWindow* owner); void PopMenuTree(); TTaskWin() : wxFrame(), m_menu(NULL), m_pOldBar(NULL) { } TTaskWin(wxWindow *parent, wxWindowID id, const wxString& title, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_FRAME_STYLE); ~TTaskWin(); DECLARE_DYNAMIC_CLASS(TTaskWin); DECLARE_EVENT_TABLE(); }; IMPLEMENT_DYNAMIC_CLASS(TwxWindow, TwxWindowBase) BEGIN_EVENT_TABLE(TwxWindow, TwxWindowBase) EVT_CHAR(TwxWindow::OnChar) EVT_KEY_DOWN(TwxWindow::OnKeyDown) EVT_CLOSE(TwxWindow::OnClose) EVT_KILL_FOCUS(TwxWindow::OnKillFocus) EVT_LEFT_DCLICK(TwxWindow::OnMouseDouble) EVT_LEFT_DOWN(TwxWindow::OnMouseDown) EVT_LEFT_UP(TwxWindow::OnMouseUp) EVT_MENU_RANGE(1000, 32766, TwxWindow::OnMenu) EVT_MIDDLE_DOWN(TwxWindow::OnMouseDown) EVT_MIDDLE_UP(TwxWindow::OnMouseUp) EVT_MOTION(TwxWindow::OnMouseMove) EVT_MOUSEWHEEL(TwxWindow::OnMouseWheel) EVT_PAINT(TwxWindow::OnPaint) EVT_RIGHT_DOWN(TwxWindow::OnMouseDown) EVT_RIGHT_UP(TwxWindow::OnMouseUp) EVT_SCROLL(TwxWindow::OnScroll) EVT_SCROLLWIN(TwxWindow::OnScrollWin) EVT_SET_FOCUS(TwxWindow::OnSetFocus) EVT_SIZE(TwxWindow::OnSize) EVT_TIMER(TIMER_ID, TwxWindow::OnTimer) END_EVENT_TABLE() void TwxWindow::DoXvtEvent(EVENT& e) { if (this != NULL && _eh != NULL) _eh((WINDOW)this, &e); } void TwxWindow::OnChar(wxKeyEvent& event) { static int nSkipNextDotKey = -883; // Valore indefinito if (nSkipNextDotKey == -883) // Devo stabilire se attivare la gestione o no { const char* campoini = xvt_fsys_get_campo_ini(); char str[2]; xvt_sys_get_profile_string(campoini, "Main", "Point2Comma", "1", str, sizeof(str)); nSkipNextDotKey = strchr("1XY", *str) != NULL ? 0 : -1; // Dis/Abilita conversione punto in virgola } EVENT e; memset(&e, 0, sizeof(EVENT)); e.type = E_CHAR; int k = event.GetKeyCode(); if (nSkipNextDotKey == 1) { nSkipNextDotKey = 0; if (k == '.') { event.Skip(); return; } } switch (k) { case WXK_ALT: case WXK_MENU: case WXK_NUMPAD0: case WXK_NUMPAD1: case WXK_NUMPAD2: case WXK_NUMPAD3: case WXK_NUMPAD4: case WXK_NUMPAD5: case WXK_NUMPAD6: case WXK_NUMPAD7: case WXK_NUMPAD8: case WXK_NUMPAD9: event.Skip(); return; case WXK_NUMPAD_DECIMAL: // Arriva solo dalla 3.6.3 in poi case WXK_DECIMAL: // ??? Arriva sia '.' sia WXK_DECIMAL=340 if (nSkipNextDotKey == 0) { k = ','; // Trasformo il punto in virgola nSkipNextDotKey = 1; } break; case WXK_NUMPAD_ADD: k = '+';break; case WXK_DOWN : k = K_DOWN; break; case WXK_END : k = K_LEND; break; case WXK_HOME : k = K_LHOME; break; case WXK_LEFT : k = K_LEFT; break; case WXK_NEXT : k = K_NEXT; break; case WXK_PRIOR: k = K_PREV; break; case WXK_RIGHT: k = K_RIGHT; break; case WXK_UP : k = K_UP; break; case WXK_TAB: if (event.ShiftDown()) k = K_BTAB; break; default: if (k >= WXK_F1 && k <= WXK_F24) k = K_F1 + k - WXK_F1; break; } e.v.chr.shift = event.ShiftDown(); e.v.chr.control = event.ControlDown(); if (event.AltDown()) { e.v.chr.control = TRUE; if (isalnum(k)) k = toupper(k); else { if (strchr("+-", k) == NULL) // Aggiungere qui vari testi eventuali { event.Skip(); return; } } } e.v.chr.ch = k; DoXvtEvent(e); } void TwxWindow::OnKeyDown(wxKeyEvent& event) { #ifdef WIN32 // Triste necessita' per gestire corretamente Alt+'+' del tasterino const int k = event.GetKeyCode(); if (k == WXK_NUMPAD_ADD) { if (event.AltDown()) { OnChar(event); return; } } #else if (event.AltDown() || event.ControlDown()) { OnChar(event); return; } #endif event.Skip(); } void TwxWindow::OnClose(wxCloseEvent& event) { EVENT e; memset(&e, 0, sizeof(EVENT)); e.type = E_DESTROY; DoXvtEvent(e); Destroy(); } void TwxWindow::OnKillFocus(wxFocusEvent& event) { if (_TheCaret.Owner() == (WINDOW)this) _TheCaret.Hide(); EVENT e; memset(&e, 0, sizeof(EVENT)); e.type = E_FOCUS; e.v.active = 0; DoXvtEvent(e); } void TwxWindow::OnMenu(wxCommandEvent& event) { EVENT e; memset(&e, 0, sizeof(EVENT)); e.type = E_COMMAND; e.v.cmd.control = 0; e.v.cmd.shift = 0; e.v.cmd.tag = event.GetId(); DoXvtEvent(e); } void TwxWindow::OnMouseDouble(wxMouseEvent& event) { EVENT e; memset(&e, 0, sizeof(EVENT)); e.type = E_MOUSE_DBL; e.v.mouse.button = (event.RightDown() ? 1 : 0) + (event.MiddleDown() ? 2 : 0); e.v.mouse.control = event.ControlDown(); e.v.mouse.shift = event.ShiftDown(); e.v.mouse.where.h = event.GetX(); e.v.mouse.where.v = event.GetY(); DoXvtEvent(e); } void TwxWindow::OnMouseDown(wxMouseEvent& event) { EVENT e; memset(&e, 0, sizeof(EVENT)); e.type = E_MOUSE_DOWN; e.v.mouse.button = (event.RightDown() ? 1 : 0) + (event.MiddleDown() ? 2 : 0); e.v.mouse.control = event.ControlDown(); e.v.mouse.shift = event.ShiftDown(); e.v.mouse.where.h = event.GetX(); e.v.mouse.where.v = event.GetY(); DoXvtEvent(e); #if wxCHECK_VERSION(2,6,1) SetFocus(); // Triste necessita' #endif } void TwxWindow::OnMouseMove(wxMouseEvent& event) { EVENT e; memset(&e, 0, sizeof(EVENT)); e.type = E_MOUSE_MOVE; e.v.mouse.button = (event.RightIsDown() ? 1 : 0) + (event.MiddleIsDown() ? 2 : 0); e.v.mouse.control = event.ControlDown(); e.v.mouse.shift = event.m_shiftDown; e.v.mouse.where.h = event.GetX(); e.v.mouse.where.v = event.GetY(); DoXvtEvent(e); } void TwxWindow::OnMouseUp(wxMouseEvent& event) { EVENT e; memset(&e, 0, sizeof(EVENT)); e.type = E_MOUSE_UP; e.v.mouse.button = (event.RightUp() ? 1 : 0) + (event.MiddleUp() ? 2 : 0); e.v.mouse.control = event.ControlDown(); e.v.mouse.shift = event.ShiftDown(); e.v.mouse.where.h = event.GetX(); e.v.mouse.where.v = event.GetY(); DoXvtEvent(e); } void TwxWindow::OnMouseWheel(wxMouseEvent& event) { const int nRot = event.GetWheelRotation(); if (nRot != 0) { EVENT e; memset(&e, 0, sizeof(EVENT)); e.type = E_VSCROLL; e.v.scroll.pos = event.GetY(); e.v.scroll.what = nRot > 0 ? SC_LINE_UP : SC_LINE_DOWN; DoXvtEvent(e); } } void TwxWindow::OnPaint(wxPaintEvent& WXUNUSED(event)) { EVENT e; memset(&e, 0, sizeof(EVENT)); e.type = E_UPDATE; RCT& rct = e.v.update.rct; wxRect rctDamaged = GetUpdateRegion().GetBox(); rct.left = rctDamaged.x; rct.top = rctDamaged.y; rct.right = rctDamaged.GetRight()+1; rct.bottom = rctDamaged.GetBottom()+1; TDC& tdc = GetTDCMapper().GetTDC((WINDOW)this); tdc.GetDC(true); // Forza la creazione di un wxPaintDC DoXvtEvent(e); tdc.KillDC(); // Distrugge il wxPaintDC GetTDCMapper().DestroyDC(NULL_WIN); // Distrugge davvero tutti i wxClientDC residui (risolve molte "porcate" del video) } static SCROLL_CONTROL ConvertScrollToXVT(wxEventType et) { if (et == wxEVT_SCROLL_TOP) return SC_THUMB; // Meglio di niente if (et == wxEVT_SCROLL_BOTTOM) return SC_THUMB; // Meglio di niente if (et == wxEVT_SCROLL_LINEUP) return SC_LINE_UP; if (et == wxEVT_SCROLL_LINEDOWN) return SC_LINE_DOWN; if (et == wxEVT_SCROLL_PAGEUP) return SC_PAGE_UP; if (et == wxEVT_SCROLL_PAGEDOWN) return SC_PAGE_DOWN; if (et == wxEVT_SCROLL_THUMBTRACK) return SC_THUMBTRACK; if (et == wxEVT_SCROLL_THUMBRELEASE) return SC_THUMB; return SC_NONE; } void TwxWindow::OnScroll(wxScrollEvent& event) { SCROLL_CONTROL sc = ConvertScrollToXVT(event.GetEventType()); if (sc != SC_NONE) { EVENT e; memset(&e, 0, sizeof(EVENT)); const wxScrollBar* sb = (wxScrollBar*)event.GetEventObject(); const wxSize sz = sb->GetSize(); e.type = E_CONTROL; e.v.ctl.id = event.GetId(); e.v.ctl.ci.type = sz.x > sz.y ? WC_HSCROLL : WC_VSCROLL; e.v.ctl.ci.win = (WINDOW)sb; e.v.ctl.ci.v.scroll.pos = event.GetPosition(); e.v.ctl.ci.v.scroll.what = sc; DoXvtEvent(e); } } void TwxWindow::OnScrollWin(wxScrollWinEvent& event) { wxEventType et = event.GetEventType(); et -= (wxEVT_SCROLLWIN_TOP - wxEVT_SCROLL_TOP); const SCROLL_CONTROL sc = ConvertScrollToXVT(et); if (sc != SC_NONE) { EVENT e; memset(&e, 0, sizeof(EVENT)); e.type = event.GetOrientation() == wxHORIZONTAL ? E_HSCROLL : E_VSCROLL; e.v.scroll.pos = event.GetPosition(); e.v.scroll.what = sc; DoXvtEvent(e); } } void TwxWindow::OnSetFocus(wxFocusEvent& event) { EVENT e; memset(&e, 0, sizeof(EVENT)); e.type = E_FOCUS; e.v.active = 1; DoXvtEvent(e); } void TwxWindow::OnSize(wxSizeEvent& event) { EVENT e; memset(&e, 0, sizeof(EVENT)); e.type = E_SIZE; e.v.size.height = event.GetSize().x; e.v.size.width = event.GetSize().y; DoXvtEvent(e); } void TwxWindow::OnTimer(wxTimerEvent& event) { EVENT e; memset(&e, 0, sizeof(EVENT)); e.type = E_TIMER; e.v.timer.id = (WINDOW)this; DoXvtEvent(e); } void TwxWindow::SetMenuTree(const MENU_ITEM* tree) { XVT_ASSERT(tree != NULL); if (tree != NULL) { if (m_menu) xvt_res_free_menu_tree(m_menu); m_menu = xvt_menu_duplicate_tree(tree); ((TTaskWin*)_task_win)->PushMenuTree(tree, this); } } TwxWindow::TwxWindow(wxWindow *parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : TwxWindowBase(parent, id, title, pos, size, style), m_menu(NULL), _eh(NULL), _timer(NULL) { _nice_windows.Put((WINDOW)this, this); } TwxWindow::~TwxWindow() { if (_timer) delete _timer; if (m_menu) { xvt_res_free_menu_tree(m_menu); ((TTaskWin*)_task_win)->PopMenuTree(); } _nice_windows.Delete((WINDOW)this); } /////////////////////////////////////////////////////////// // Main application = TASK_WIN functions /////////////////////////////////////////////////////////// IMPLEMENT_DYNAMIC_CLASS(TTaskWin, wxFrame) BEGIN_EVENT_TABLE(TTaskWin, wxFrame) EVT_CLOSE(TTaskWin::OnClose) EVT_MENU_RANGE(1000, 32766, TTaskWin::OnMenu) EVT_PAINT(TTaskWin::OnPaint) EVT_SIZE(TTaskWin::OnSize) END_EVENT_TABLE() void TTaskWin::OnClose(wxCloseEvent& event) { if (event.CanVeto()) { EVENT e; memset(&e, 0, sizeof(EVENT)); e.type = E_CLOSE; int veto = _task_win_handler((WINDOW)this, &e); event.Veto(veto != 0); } else event.Skip(); } void TTaskWin::OnMenu(wxCommandEvent& event) { EVENT e; memset(&e, 0, sizeof(EVENT)); e.type = E_COMMAND; e.v.cmd.control = 0; e.v.cmd.shift = 0; e.v.cmd.tag = event.GetId(); if (m_MenuOwner == NULL || m_MenuOwner == this) _task_win_handler((WINDOW)this, &e); else ((TwxWindow*)m_MenuOwner)->_eh((WINDOW)m_MenuOwner, &e); } void TTaskWin::OnPaint(wxPaintEvent& WXUNUSED(event)) { EVENT e; memset(&e, 0, sizeof(EVENT)); e.type = E_UPDATE; RCT& rct = e.v.update.rct; wxRect rctDamaged = GetUpdateRegion().GetBox(); rct.left = rctDamaged.x; rct.top = rctDamaged.y; rct.right = rctDamaged.GetRight()+1; rct.bottom = rctDamaged.GetBottom()+1; TDC& dc = GetTDCMapper().GetTDC((WINDOW)this); dc.GetDC(true); // Forza la creazione di un wxPaintDC _task_win_handler((WINDOW)this, &e); dc.KillDC(); } void TTaskWin::OnSize(wxSizeEvent& event) { EVENT e; memset(&e, 0, sizeof(EVENT)); e.type = E_SIZE; e.v.size.height = event.GetSize().x; e.v.size.width = event.GetSize().y; _task_win_handler((WINDOW)this, &e); } void TTaskWin::SetMenuTree(const MENU_ITEM* tree) { if (m_menu) xvt_res_free_menu_tree(m_menu); m_menu = xvt_menu_duplicate_tree(tree); wxMenuBar* bar = GetMenuBar(); for ( ; tree != NULL && tree->tag != 0; tree++) { wxMenu* pMenu = new wxMenu; for (MENU_ITEM* mi = tree->child; mi != NULL && mi->tag != 0; mi++) { wxMenuItem* item = NULL; if (mi->separator) item = new wxMenuItem(pMenu, wxID_SEPARATOR); else item = new wxMenuItem(pMenu, mi->tag, mi->text, wxEmptyString, mi->checkable); pMenu->DoAppend(item); } const int nLast = bar->GetMenuCount()-1; int m; for (m = 2; m < nLast; m++) { wxMenu* pMenu = bar->GetMenu(m); if (pMenu->FindItem(tree->child->tag)) { bar->Remove(m); // delete pMenu; break; } } bar->Insert(m, pMenu, tree->text); } } void TTaskWin::PushMenuTree(const MENU_ITEM* tree, wxWindow* owner) { if(m_pOldBar != NULL) PopMenuTree(); m_pOldBar = GetMenuBar(); wxMenuBar* pBar = new wxMenuBar; for (; tree && tree->tag != 0; tree++) { wxMenu* pMenu = new wxMenu; for (MENU_ITEM* mi = tree->child; mi != NULL && mi->tag != 0; mi++) { wxMenuItem* item = NULL; if (mi->separator) item = new wxMenuItem(pMenu, wxID_SEPARATOR); else item = new wxMenuItem(pMenu, mi->tag, mi->text, wxEmptyString, mi->checkable); pMenu->DoAppend(item); } pBar->Append(pMenu, tree->text); } SetMenuBar(pBar); m_MenuOwner = owner; } void TTaskWin::PopMenuTree() { XVT_ASSERT(m_pOldBar != NULL); wxMenuBar* pBar = GetMenuBar(); SetMenuBar(m_pOldBar); delete pBar; m_pOldBar = NULL; m_MenuOwner = NULL; // = this; } TTaskWin::TTaskWin(wxWindow *parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style), m_menu(NULL), m_pOldBar(NULL), m_MenuOwner(NULL) { wxIcon* ico = ::GetIconResource(ICON_RSRC); if (ico) SetIcon(*ico); _nice_windows.Put((WINDOW)this, this); } TTaskWin::~TTaskWin() { if (m_menu) { xvt_res_free_menu_tree(m_menu); m_menu = NULL; } _nice_windows.Delete((WINDOW)this); } /////////////////////////////////////////////////////////// // Speech support /////////////////////////////////////////////////////////// // 0 Errors // 1 Warnings // 2 Messages // 3 Requests // 7 Buttons static int m_nSpeechMode = 0; void xvt_dm_enable_speech(int mode) { #ifdef SPEECH_API m_nSpeechMode = mode; #ifdef WIN32 if (m_nSpeechMode != 0) { if (!OsWin32_InitializeSpeech()) m_nSpeechMode = 0; } else { OsWin32_DeinitializeSpeech(); } #endif #endif } /////////////////////////////////////////////////////////// // XVT /////////////////////////////////////////////////////////// void xvt_app_allow_quit(void) { wxTheApp->ExitMainLoop(); // Già lo fa la destroy } void xvt_app_create(int argc, char **argv, unsigned long flags, EVENT_HANDLER eh, XVT_CONFIG *config) { ::wxInitAllImageHandlers(); xvt_fsys_get_default_dir(NULL); // Init Startup Directory #ifdef SPEECH_API xvt_dm_enable_speech(0xFF); #endif _task_win_handler = eh; _config_ = config; const wxString title = config->taskwin_title; #ifdef WIN32 wxPoint pos = wxDefaultPosition; wxSize size = wxDefaultSize; #else wxRect rect = wxGetClientDisplayRect(); wxPoint pos; wxSize size ; pos.x = rect.x; pos.y = rect.y; size.x = rect.width; size.y = rect.height; #endif long style = wxDEFAULT_FRAME_STYLE; if (_startup_rect.right > _startup_rect.left) { pos.x = _startup_rect.left; pos.y = _startup_rect.top; size.x = _startup_rect.right - _startup_rect.left; size.y = _startup_rect.bottom - _startup_rect.top; } else { #ifdef WIN32 style |= wxMAXIMIZE; #else style &= ~wxMAXIMIZE; #endif } _task_win = new TTaskWin(NULL, ICON_RSRC, title, pos, size, style); #if wxCHECK_VERSION(2,6,1) _task_win->SetBackgroundStyle(wxBG_STYLE_CUSTOM); // Lo sfondo viene disegnato nella OnPaint #endif _nice_windows.Put((WINDOW)_task_win, _task_win); wxMenu* Menus[3]; wxString Title[3]; Title[0] = "&File"; Menus[0] = new wxMenu; Menus[0]->Append(M_FILE_NEW, "Scelta &Ditta..."); Menus[0]->AppendSeparator(); Menus[0]->Append(M_FILE_PG_SETUP, "&Impostazione Stampante..."); Menus[0]->Append(M_FILE_PRINT, "&Stampa"); Menus[0]->AppendSeparator(); Menus[0]->Append(M_FILE_QUIT, "&Fine"); Title[1] = "&Modifica"; Menus[1] = new wxMenu; Menus[1]->Append(M_EDIT_CUT, "&Taglia\tCtrl+X"); Menus[1]->Append(M_EDIT_COPY, "&Copia\tCtrl+C"); Menus[1]->Append(M_EDIT_PASTE, "&Incolla\tCtrl+V"); Menus[1]->Append(M_EDIT_CLEAR, "&Elimina\tCanc"); Title[2] = "&Help"; Menus[2] = new wxMenu; Menus[2]->Append(M_HELP_CONTENTS, "&Sommario"); Menus[2]->Append(M_HELP_SEARCH, "&Cerca argomento"); Menus[2]->Append(M_HELP_HELPONHELP, "&Uso della guida"); Menus[2]->AppendSeparator(); Menus[2]->Append(M_FILE_ABOUT+1, "&Informazioni"); #ifdef WIN32 wxMenuBar* pMenubar = new wxMenuBar(3, Menus, Title); #else wxMenuBar* pMenubar = new wxMenuBar(); for (int i= 0; i < 3; i++) pMenubar->Append(Menus[i], Title[i]); #endif ((wxFrame*)_task_win)->SetMenuBar(pMenubar); if (style & wxMAXIMIZE) ((wxFrame*)_task_win)->Maximize(); _task_win->Show(); wxApp* a = wxTheApp; a->SetTopWindow(_task_win); EVENT e; memset(&e, 0, sizeof(e)); e.type = E_CREATE; long ret = _task_win_handler((WINDOW)_task_win, &e); if (ret != 0) { // Simula main loop #if wxCHECK_VERSION(2,6,1) xvt_app_process_pending_events(); #else a->MainLoop(); #endif } a->ExitMainLoop(); // Non entrare nel main loop di wxWindows } void xvt_app_destroy(void) { wxTheApp->ExitMainLoop(); _task_win->Destroy(); #ifdef SPEECH_API xvt_dm_enable_speech(0x00); #endif } DRAW_CTOOLS* xvt_app_get_default_ctools(DRAW_CTOOLS *ct) { XVT_ASSERT(ct != NULL); TDC dc(NULL); memcpy(ct, &dc._dct, sizeof(DRAW_CTOOLS)); return ct; } void xvt_app_process_pending_events(void) { wxApp* a = wxTheApp; // Memorizzo il risultato di wxGetInstance if (a != NULL) { #if wxCHECK_VERSION(2,6,1) while (a->Pending()) a->Dispatch(); a->Yield(true); #else for (int m = 0; m < 4 && a->Pending(); m++) a->Dispatch(); #endif } } /////////////////////////////////////////////////////////// // Clipboard functions /////////////////////////////////////////////////////////// static DATA_PTR ptrClipboardData = NULL; char* xvt_cb_alloc_data(long size) { xvt_cb_free_data(); if (size > 0) ptrClipboardData = xvt_mem_zalloc(size+1); return ptrClipboardData; } BOOLEAN xvt_cb_close(void) { wxTheClipboard->Close(); wxTheClipboard->Flush(); return TRUE; } void xvt_cb_free_data(void) { if (ptrClipboardData != NULL) { xvt_mem_free(ptrClipboardData); ptrClipboardData = NULL; } } char* xvt_cb_get_data(CB_FORMAT cbfmt, char *name, long *sizep) { if (xvt_cb_has_format(cbfmt, name)) { wxTextDataObject data; wxTheClipboard->GetData(data); *sizep = data.GetDataSize(); if (*sizep > 0) { xvt_cb_alloc_data(*sizep); memcpy(ptrClipboardData, data.GetText(), *sizep); (*sizep)--; // Elimino lo '/0' finale che non piace a XI return ptrClipboardData; } } sizep = 0; return NULL; } BOOLEAN xvt_cb_has_format(CB_FORMAT fmt, char *name) { BOOLEAN ok = fmt == CB_TEXT && wxTheClipboard->IsSupported(wxDF_TEXT); return ok; } BOOLEAN xvt_cb_open(BOOLEAN writing) { wxTheClipboard->Open(); return TRUE; } BOOLEAN xvt_cb_put_data(CB_FORMAT cbfmt, char *name, long size, PICTURE pic) { BOOLEAN ok = cbfmt == CB_TEXT && ptrClipboardData != NULL; if (ok) wxTheClipboard->SetData(new wxTextDataObject(ptrClipboardData)); return ok; } /////////////////////////////////////////////////////////// // Controls functions (NOT used) /////////////////////////////////////////////////////////// class TwxScrollBar : public wxScrollBar { protected: virtual bool AcceptsFocus() const { return false; } // Altrimenti mette il flag wxTAB_TRAVERSAL public: TwxScrollBar(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style) { Create(parent, id, pos, size, style); } }; WINDOW xvt_ctl_create_def(WIN_DEF *win_def_p, WINDOW parent_win, long app_data) { WINDOW win = NULL_WIN; switch (win_def_p->wtype) { case WC_HSCROLL: /* horizontal scrollbar control */ case WC_VSCROLL: /* vertical scrollbar control */ { const wxRect rct = NormalizeRCT(&win_def_p->rct); long style = win_def_p->wtype == WC_HSCROLL ? wxSB_HORIZONTAL : wxSB_VERTICAL; TwxScrollBar* sb = new TwxScrollBar((wxWindow*)parent_win, win_def_p->v.ctl.ctrl_id, rct.GetPosition(), rct.GetSize(), style); win = (WINDOW)sb; } break; default: SORRY_BOX(); break; } return win; } void xvt_ctl_check_radio_button(WINDOW Win, WINDOW* Wins, int NbrWindows) { SORRY_BOX(); } // Ignored void xvt_ctl_set_checked(WINDOW Win, BOOLEAN Check) { SORRY_BOX(); } // Ignored /////////////////////////////////////////////////////////// // Debug functions /////////////////////////////////////////////////////////// void xvt_debug_printf(const char* fmt, ...) { #ifndef NDEBUG static FILE* f = NULL; if (f == NULL) f = fopen("trace.log", "w"); if (f != NULL) { char msg[256]; va_list argptr; va_start(argptr,fmt); vsprintf(msg,fmt,argptr); va_end(argptr); fprintf(f, "%s\n", msg); fflush(f); } #endif } /////////////////////////////////////////////////////////// // Dongle functions /////////////////////////////////////////////////////////// BOOLEAN xvt_dongle_hl_crypt(unsigned short* data) // Array di 4 words (8 bytes) { #ifdef WIN32 return OsWin32_HL_Crypt(data); #else return OsLinux_HL_Crypt(data); #endif return FALSE; } BOOLEAN xvt_dongle_hl_login(unsigned short address, const unsigned char* label, const unsigned char* password) { #ifdef WIN32 return OsWin32_HL_Login(address, label, password); #else return OsLinux_HL_Login(address, label, password); #endif return FALSE; } BOOLEAN xvt_dongle_hl_logout() { #ifdef WIN32 return OsWin32_HL_Logout(); #else return OsLinux_HL_Logout(); #endif return TRUE; } BOOLEAN xvt_dongle_hl_read(unsigned short reg, unsigned short* data) { #ifdef WIN32 return OsWin32_HL_Read(reg, data); #else return OsLinux_HL_Read(reg, data); #endif return FALSE; } BOOLEAN xvt_dongle_hl_read_block(unsigned char* data) { #ifdef WIN32 return OsWin32_HL_ReadBlock(data); #else return OsLinux_HL_ReadBlock(data); #endif return FALSE; } BOOLEAN xvt_dongle_hl_write(unsigned short reg, unsigned short data) { #ifdef WIN32 return OsWin32_HL_Write(reg, data); #else return OsLinux_HL_Write(reg, data); #endif return FALSE; } BOOLEAN xvt_dongle_sl_crypt(unsigned short* data) { #ifdef WIN32 return OsWin32_SL_Crypt(data); #else return OsLinux_SL_Crypt(data); #endif return FALSE; } BOOLEAN xvt_dongle_sl_login(const unsigned char* label, const unsigned char* password) { #ifdef WIN32 return OsWin32_SL_Login(label, password); #else return OsLinux_SL_Login(label, password); #endif return FALSE; } BOOLEAN xvt_dongle_sl_logout() { #ifdef WIN32 return OsWin32_SL_Logout(); #else return OsLinux_SL_Logout(); #endif return TRUE; } BOOLEAN xvt_dongle_sl_read_block(unsigned short reg, unsigned short size, unsigned short* data) { #ifdef WIN32 return OsWin32_SL_ReadBlock(reg, size, data); #else return OsLinux_SL_ReadBlock(reg, size, data); #endif return FALSE; } BOOLEAN xvt_dongle_sl_write_block(unsigned short reg, unsigned short size, const unsigned short* data) { #ifdef WIN32 return OsWin32_SL_WriteBlock(reg, size, data); #else return OsLinux_SL_WriteBlock(reg, size, data); #endif return FALSE; } /////////////////////////////////////////////////////////// // Common dialogs /////////////////////////////////////////////////////////// wxString _GetAppTitle() { wxString strTitle; if (_config_ != NULL) strTitle = _config_->appl_name; else strTitle = "CAMPO"; return strTitle; } COLOR xvt_dm_post_choose_color(WINDOW win, COLOR xc) { CAST_COLOR(xc, wc); wxColourData cd; cd.SetChooseFull(true); cd.SetColour(wc); for (int i = 0; i < 16; i++) { const unsigned char val = (i & 0x8) ? 255 : 127; const unsigned char red = (i & 0x1) ? val : 0; const unsigned char green = (i & 0x2) ? val : 0; const unsigned char blue = (i & 0x4) ? val : 0; wxColour col(red, green, blue); cd.SetCustomColour(i, col); } CAST_WIN(win, w); wxColourDialog dialog(&w, &cd); if (dialog.ShowModal() == wxID_OK) xc = MAKE_XVT_COLOR(dialog.GetColourData().GetColour()); return xc; } class TwxCalendarDlg : public wxDialog { enum { ID_CAL = 1883 }; wxDateTime& m_date; wxCalendarCtrl* m_cal; protected: virtual bool TransferDataFromWindow(); void OnCalendar(wxCalendarEvent& event); public: TwxCalendarDlg(wxWindow* parent, const wxPoint& pnt, wxDateTime& date); DECLARE_EVENT_TABLE() }; BEGIN_EVENT_TABLE(TwxCalendarDlg, wxDialog) EVT_CALENDAR(wxID_ANY, TwxCalendarDlg::OnCalendar) END_EVENT_TABLE() void TwxCalendarDlg::OnCalendar(wxCalendarEvent& event) { wxCommandEvent evt(wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK); AddPendingEvent(evt); } bool TwxCalendarDlg::TransferDataFromWindow() { bool ok = wxDialog::TransferDataFromWindow(); if (ok) { m_date = m_cal->GetDate(); } return ok; } TwxCalendarDlg::TwxCalendarDlg(wxWindow* parent, const wxPoint& pnt, wxDateTime& date) : wxDialog(parent, wxID_ANY, "Data", pnt, wxDefaultSize, wxRAISED_BORDER), m_date(date) { m_cal = new wxCalendarCtrl(this, ID_CAL, m_date, pnt, wxDefaultSize, wxCAL_MONDAY_FIRST | wxCAL_SHOW_HOLIDAYS | wxCAL_SHOW_SURROUNDING_WEEKS); wxButton* button = new wxButton(this, wxID_OK, "OK"); wxGridSizer* sizer = new wxFlexGridSizer(2, 1, 8, 8); sizer->Add(m_cal, 0, wxALIGN_CENTER); sizer->Add(button, 0, wxALIGN_CENTER); SetSizer(sizer); sizer->SetSizeHints(this); } unsigned int xvt_dm_post_choose_date(WINDOW win, PNT pos, unsigned int ansidate) { int d = ansidate%100; int m = (ansidate/100)%100; int y = ansidate / 10000; wxDateTime date; if (d >= 1 && d <= 31 && m >= 1 && m <= 12 && y > 1900) date.Set(d, wxDateTime::Month(m-1), y); else date = wxDateTime::Today(); CAST_WIN(win, w); wxPoint pnt(pos.h, pos.v); if (pos.h < 0 || pos.v < 0) pnt = wxDefaultPosition; else pnt = w.ClientToScreen(pnt); wxDialog* dlg = new TwxCalendarDlg(&w, pnt, date); if (dlg->ShowModal() == wxID_OK) { d = date.GetDay(); m = date.GetMonth()+1; y = date.GetYear(); ansidate = y*10000 + m*100 + d; } dlg->Destroy(); return ansidate; } BOOLEAN xvt_dm_post_speech(const char* text, int priority, BOOLEAN async) { BOOLEAN ok = FALSE; #ifdef SPEECH_API if ((m_nSpeechMode & (1 << priority)) != 0) { #ifdef WIN32 ok = OsWin32_Speak(text, async != 0); #endif } #endif return ok; } ASK_RESPONSE xvt_dm_post_ask(const char* Btn1, const char*Btn2, const char* Btn3, const char* fmt) { int nFlags = wxCENTRE | wxICON_QUESTION | wxYES_NO; if (Btn3 == NULL) { if (wxStricmp(Btn1, "no") == 0) nFlags |= wxNO_DEFAULT; } else nFlags |= wxCANCEL; xvt_dm_post_speech(fmt, 3, TRUE); const int answer = wxMessageBox(fmt, _GetAppTitle(), nFlags); switch(answer) { case wxYES: xvt_dm_post_speech("si", 7, TRUE); break; case wxNO : xvt_dm_post_speech("no", 7, TRUE); break; default : xvt_dm_post_speech("annulla", 7, TRUE); break; } return answer == wxYES ? RESP_DEFAULT : (answer == wxNO ? RESP_2 : RESP_3); } void xvt_dm_post_error(const char *fmt) { xvt_dm_post_speech(fmt, 1, TRUE); wxMessageBox(fmt, _GetAppTitle(), wxOK | wxCENTRE | wxICON_ERROR); xvt_dm_post_speech("OK", 7, TRUE); } void xvt_dm_post_fatal_exit(const char *fmt) { xvt_dm_post_speech(fmt, 1, TRUE); wxLogFatalError(fmt); xvt_dm_post_speech("OK", 7, TRUE); } static wxString MakeFileName(const wxChar* name, const wxChar* ext) { wxString f = name; if (ext && *ext) { if (*ext != '.') f += '.'; f += ext; } return f; } static FL_STATUS xvt_dm_post_file_ask(FILE_SPEC *fsp, const char *msg, int flags) { wxString path = fsp->dir.path; wxString name = MakeFileName(fsp->name, fsp->type); wxString extension = fsp->type; wxString mask = MakeFileName("*", fsp->type); wxString selectedname = wxFileSelector(msg, path, name, extension , mask, flags); if (selectedname.IsEmpty()) return FL_CANCEL; wxFileName::SplitPath(selectedname, &path, &name, &extension); strcpy(fsp->dir.path, path); strcpy(fsp->name, MakeFileName(name, extension)); strcpy(fsp->type, extension); return FL_OK; } FL_STATUS xvt_dm_post_file_open(FILE_SPEC *fsp, const char *msg) { #if wxCHECK_VERSION(2,6,1) const int flags = wxOPEN | wxFILE_MUST_EXIST; #else const int flags = wxOPEN | wxHIDE_READONLY | wxFILE_MUST_EXIST; #endif return xvt_dm_post_file_ask(fsp, msg, flags); } FL_STATUS xvt_dm_post_file_save(FILE_SPEC *fsp, const char *msg) { #if wxCHECK_VERSION(2,6,1) const int flags = wxSAVE; #else const int flags = wxSAVE | wxHIDE_READONLY; #endif return xvt_dm_post_file_ask(fsp, msg, flags); } FL_STATUS xvt_dm_post_dir_sel(DIRECTORY *dir) { wxDirDialog dlg(_task_win); dlg.SetPath(dir->path); if (dlg.ShowModal() == wxID_OK) { xvt_fsys_convert_str_to_dir(dlg.GetPath(), dir); return FL_OK; } return FL_CANCEL; } BOOLEAN xvt_dm_post_font_sel(WINDOW win, XVT_FNTID font_id, PRINT_RCD *precp, unsigned long reserved) { TFontId& font = *(TFontId*)font_id; wxFontData data; data.SetInitialFont(font.Font(NULL, win)); data.EnableEffects(reserved != 0); wxFontDialog dlg(_task_win, &data); BOOLEAN ok = dlg.ShowModal() == wxID_OK; if (ok) { font.Copy(dlg.GetFontData().GetChosenFont()); if (win == (WINDOW)_task_win) { EVENT e; memset(&e, 0, sizeof(EVENT)); e.type = E_FONT; e.v.font.font_id = font_id; _task_win_handler(win, &e); } } return ok; } void xvt_dm_post_message(const char *fmt) { xvt_dm_post_speech(fmt, 2, TRUE); wxMessageBox(fmt, _GetAppTitle(), wxOK | wxCENTRE | wxICON_INFORMATION); xvt_dm_post_speech("OK", 7, TRUE); } void xvt_dm_post_note(const char *fmt) { xvt_dm_post_speech(fmt, 2, TRUE); wxMessageBox(fmt, _GetAppTitle(), wxOK | wxCENTRE | wxICON_EXCLAMATION); xvt_dm_post_speech("OK", 7, TRUE); } char* xvt_dm_post_string_prompt(const char* message, char* response, int response_len) { XVT_ASSERT(message && response && response_len > 0); SORRY_BOX(); *response = '\0'; return NULL; } void xvt_dm_post_warning(const char *fmt) { xvt_dm_post_speech(fmt, 1, TRUE); wxMessageBox(fmt, _GetAppTitle(), wxOK | wxCENTRE | wxICON_EXCLAMATION); xvt_dm_post_speech("OK", 7, TRUE); } /////////////////////////////////////////////////////////// // Help system /////////////////////////////////////////////////////////// struct XVAGA_HELP_INFO { wxString m_strFilename; bool m_hlp; } help_info; XVT_HELP_INFO xvt_help_open_helpfile(FILE_SPEC *fs, unsigned long flags) { return (XVT_HELP_INFO)&help_info; } void xvt_help_close_helpfile(XVT_HELP_INFO hi) { if (hi == NULL_HELP_INFO) hi = (XVT_HELP_INFO)&help_info; } BOOLEAN xvt_help_process_event(XVT_HELP_INFO hi, WINDOW win, EVENT *ev) { BOOLEAN bProcessed = FALSE; #ifdef WIN32 WXHWND hwnd = (WXHWND)xvt_vobj_get_attr(win, ATTR_NATIVE_WINDOW); switch (ev->type) { case E_COMMAND: bProcessed = OsWin32_Help(hwnd, "", ev->v.cmd.tag, NULL); break; case E_HELP: bProcessed = OsWin32_Help(hwnd, "", M_HELP_ONCONTEXT, (const char*)ev->v.help.tid); break; default: break; } #endif // WIN32 return bProcessed; } /////////////////////////////////////////////////////////// // Image handling /////////////////////////////////////////////////////////// class TXVT_IMAGE { wxImage m_image; int m_nDepth; bool m_bDirty; #ifdef WIN32 HBITMAP m_bitmap; #else wxBitmap* m_bitmap; #endif protected: void Destroy(); public: const wxImage& Image() const { return m_image; } wxImage& Image() { m_bDirty = true; return m_image; } #ifdef WIN32 HBITMAP Bitmap(wxDC& dc); #else const wxBitmap& Bitmap(wxDC& dc); #endif TXVT_IMAGE() : m_bitmap(NULL), m_nDepth(0), m_bDirty(false) { } ~TXVT_IMAGE(); }; #ifdef WIN32 HBITMAP TXVT_IMAGE::Bitmap(wxDC& dc) { if (m_bDirty || m_bitmap == NULL || dc.GetDepth() != m_nDepth) { Destroy(); m_nDepth = dc.GetDepth(); m_bDirty = FALSE; m_bitmap = OsWin32_CreateBitmap(m_image, dc); } return m_bitmap; } #else const wxBitmap& TXVT_IMAGE::Bitmap(wxDC& dc) { if (m_bDirty || m_bitmap == NULL || dc.GetDepth() != m_nDepth) { Destroy(); m_nDepth = dc.GetDepth(); m_bDirty = FALSE; m_bitmap = new wxBitmap(m_image, m_nDepth); } return *m_bitmap; } #endif void TXVT_IMAGE::Destroy() { if (m_bitmap != NULL) #ifdef WIN32 ::DeleteObject(m_bitmap); #else delete m_bitmap; #endif m_bitmap = NULL; } TXVT_IMAGE::~TXVT_IMAGE() { Destroy(); } /////////////////////////////////////////////////////////// // Font Handling /////////////////////////////////////////////////////////// void TFontId::Copy(const TFontId& rFont) { m_strFace = rFont.m_strFace; m_nSize = rFont.m_nSize; m_wMask = rFont.m_wMask; m_win = rFont.m_win; } bool TFontId::IsEqual(const TFontId& rFont) const { if (m_strFace != rFont.m_strFace) return false; if (m_nSize != rFont.m_nSize) return false; if (m_wMask != rFont.m_wMask) return false; return true; } const char* TFontId::FaceName() const { if (m_strFace.IsEmpty()) return XVT_FFN_COURIER; return m_strFace; } int TFontId::Family() const { if (m_strFace.IsEmpty() || m_strFace == XVT_FFN_COURIER) return wxMODERN; if (m_strFace == XVT_FFN_HELVETICA) return wxSWISS; if (m_strFace == XVT_FFN_TIMES) return wxROMAN; if (m_strFace == XVT_FFN_FIXED) return wxMODERN; if (m_strFace == XVT_FFN_SYSTEM) return wxDEFAULT; return wxSWISS; } int TFontId::Style() const { return (m_wMask & XVT_FS_ITALIC) ? wxITALIC : wxNORMAL; } bool TFontId::Underline() const { return (m_wMask & XVT_FS_UNDERLINE) != 0; } int TFontId::Weight() const { return (m_wMask & XVT_FS_BOLD) ? wxBOLD : wxNORMAL; } wxFont& TFontId::Font(wxDC* dc, WINDOW win) const { int nSize = PointSize(); if (win == PRINTER_WIN) { static wxDC* lastDC = NULL; static wxSize lastPPI; static double dPrintScale = 1.0; const wxSize ppi = dc->GetPPI(); if (dc != lastDC || ppi != lastPPI) { #ifdef WIN32 const char* const DEFAULT_FONT_NAME = "Courier New"; #else const char* const DEFAULT_FONT_NAME = "Courier"; #endif const int nTarget10 = 10 * ppi.x; // pixel in 10 pollici in larghezza const int cpi10 = 10 * 120 / nSize; // caratteri stimati in 10 pollici const wxString str('M', cpi10); // stringa campione per stimare la larghezza int nMin = 1, nMax = nSize*16; // Limiti arbitrari int nBest = 0; while (nMin <= nMax) { const int nFontSize = (nMin+nMax)/2; wxFont courier(nFontSize, wxFIXED, wxNORMAL, wxNORMAL, FALSE, DEFAULT_FONT_NAME); dc->SetFont(courier); int tw; dc->GetTextExtent(str, &tw, NULL); if (tw <= nTarget10) { nMin = nFontSize+1; nBest = nFontSize; if (tw == nTarget10) break; } else nMax = nFontSize-1; } if (nBest == 0) nBest = nMax; #ifdef WIN32 // Pezza per cercare di ovviare a dimensioni assurde calcolate dai sistemi Win * // Praticamente succede che il Courier 70 sia piu' piccolo del Curier 60 // Per cui una volta candidata una dimensione (nBest) tramite le righe precedenti // cerco il primo font piu' piccolo che non sfonda bool bPrevGood = true; for (int i = 15; i > 0; i--) { const int nFontSize = nBest-i; wxFont courier(nFontSize, wxFIXED, wxNORMAL, wxNORMAL, FALSE, DEFAULT_FONT_NAME); dc->SetFont(courier); int tw, th; dc->GetTextExtent(str, &tw, &th); if (tw > nTarget10 && bPrevGood) { nBest = nFontSize-1; break; } bPrevGood = tw <= nTarget10; } #endif dPrintScale = double(nBest) / double(nSize); #ifdef LINUX dPrintScale /= 10.0; // * wxPostScriptDC::GetResolution()) / 72.0); #endif lastDC = dc; lastPPI = ppi; } nSize = (int)(nSize * dPrintScale + 0.5); } wxFont* font = wxTheFontList->FindOrCreateFont( nSize, Family(), Style(), Weight(), Underline(), FaceName()); return *font; } void TFontId::Copy(const wxFont& rFont) { m_strFace = rFont.GetFaceName(); m_nSize = rFont.GetPointSize(); m_wMask = XVT_FS_NONE; if (rFont.GetUnderlined()) m_wMask |= XVT_FS_UNDERLINE; if (rFont.GetWeight() >= wxBOLD) m_wMask |= XVT_FS_BOLD; if (rFont.GetStyle() == wxITALIC) m_wMask |= XVT_FS_ITALIC; m_win = NULL_WIN; } /////////////////////////////////////////////////////////// // Drawable windows /////////////////////////////////////////////////////////// void xvt_dwin_clear(WINDOW win, COLOR col) { CAST_DC(win, dc); CAST_COLOR(col, brush_color); wxBrush* brush = wxTheBrushList->FindOrCreateBrush(brush_color, wxSOLID); dc.SetBackground(*brush); dc.Clear(); } void xvt_dwin_draw_arc(WINDOW win, const RCT* r, int sx, int sy, int ex, int ey) { if (r != NULL) { CAST_DC(win, dc); dc.DrawArc(sx, sy, ex, ey, (r->right+r->left)/2, (r->top+r->bottom)/2); } } void xvt_dwin_draw_icon(WINDOW win, int x, int y, int rid) { wxIcon* ico = ::GetIconResource(rid); if (ico != NULL) { CAST_DC(win, dc); dc.DrawIcon(*ico, x, y); } } static wxRect ComputeRect(const wxRect& rct, int h, int v, int k) { const int sx = rct.x + h * rct.width / k; const int ex = rct.x + (h+1) * rct.width / k; const int sy = rct.y + v * rct.height / k; const int ey = rct.y + (v+1) * rct.height / k; return wxRect(sx, sy, ex-sx, ey-sy); } static void DrawImageOnDC(wxDC& dc, TXVT_IMAGE* image, const wxRect& dst, const wxRect& src) { #ifdef WIN32 if (!OsWin32_DrawBitmap(image->Bitmap(dc), dc, dst, src)) { const int k = 4; for (int h = 0; h < k; h++) { for (int v = 0; v < k; v++) { const wxRect destin = ComputeRect(dst, h, v, k); wxRect source = ComputeRect(src, h, v, k); wxImage img = image->Image().GetSubImage(source); source.x = source.y = 0; wxBitmap bmp(img); OsWin32_DrawBitmap((HBITMAP)bmp.GetHBITMAP(), dc, destin, source); } } } #else const wxBitmap& bmp = image->Bitmap(dc); const bool printing = is_printer_dc(&dc); if (src.GetPosition() == wxPoint(0,0) && src.GetSize() == dst.GetSize() && bmp.Ok()) dc.DrawBitmap(bmp, dst.GetX(), dst.GetY(), !printing); else { wxImage img = image->Image().GetSubImage(src); if (dst.GetHeight() < src.GetHeight() || dst.GetWidth() < src.GetWidth()) img.Rescale(dst.GetWidth() * 4, dst.GetHeight() * 4); img.Rescale(dst.GetWidth(), dst.GetHeight()); wxBitmap bmp(img); dc.DrawBitmap(bmp, dst.GetX(), dst.GetY(), !printing); } #endif } void xvt_dwin_draw_image(WINDOW win, XVT_IMAGE image, RCT* dest, RCT* source) { XVT_ASSERT(image != NULL); if (image != NULL) { if (xvt_dwin_is_update_needed(win, dest)) { CAST_DC(win, dc); const wxRect src = NormalizeRCT(source); const wxRect dst = NormalizeRCT(dest); DrawImageOnDC(dc, (TXVT_IMAGE*)image, dst, src); } } } void xvt_dwin_draw_oval(WINDOW win, const RCT* rctp) { CAST_DC(win, dc); const wxRect rct = NormalizeRCT(rctp); dc.DrawEllipse(rct); } void xvt_dwin_draw_pie(WINDOW win, const RCT *rctp, int start_x, int start_y, int stop_x, int stop_y) { SORRY_BOX(); } void xvt_dwin_draw_polygon(WINDOW win, const PNT *lpnts, int npnts) { if (lpnts != NULL && npnts > 1) { CAST_DC(win, dc); wxPoint* pt = new wxPoint[npnts]; for (int i = 0; i < npnts; i++) { pt[i].x = lpnts[i].h; pt[i].y = lpnts[i].v; } dc.DrawPolygon(npnts, pt); delete pt; } } void xvt_dwin_draw_polyline(WINDOW win, const PNT *lpnts, int npnts) { if (lpnts != NULL && npnts > 1) { xvt_dwin_draw_set_pos(win, lpnts[0]); for (int i = 1; i < npnts; i++) xvt_dwin_draw_line(win, lpnts[i]); } } void xvt_dwin_draw_rect(WINDOW win, RCT *rctp) { CAST_DC(win, dc); const wxRect rct = NormalizeRCT(rctp); dc.DrawRectangle(rct); } void xvt_dwin_draw_roundrect(WINDOW win, const RCT *rctp, int oval_width, int oval_height) { CAST_DC(win, dc); const wxRect rct = NormalizeRCT(rctp); dc.DrawRoundedRectangle(rct, min(oval_width, oval_height)); } void xvt_dwin_draw_dotted_rect(WINDOW win, RCT *rctp) { #ifdef WIN32 static int can_draw_dots = -1; if (can_draw_dots < 0) can_draw_dots = xvt_sys_get_os_version() >= XVT_WS_WIN_NT; if (can_draw_dots) { CAST_DC(win, dc); OsWin32_DrawDottedRect(dc.GetHDC(), rctp->left, rctp->top, rctp->right, rctp->bottom); return; } #endif DRAW_CTOOLS dct; xvt_dwin_get_draw_ctools(win, &dct); CPEN pen; pen.width = 1; pen.pat = PAT_SOLID; pen.style = P_DOT; pen.color = dct.fore_color; xvt_dwin_set_cpen(win, &pen); CBRUSH brush; brush.color = dct.back_color; brush.pat = PAT_HOLLOW; xvt_dwin_set_cbrush(win, &brush); xvt_dwin_draw_rect(win, rctp); xvt_dwin_set_draw_ctools(win, &dct); } void xvt_dwin_draw_set_pos(WINDOW win, PNT pnt) { CAST_TDC(win, dc); dc._pnt.x = pnt.h; dc._pnt.y = pnt.v; } void xvt_dwin_draw_text(WINDOW win, int x, int y, const char *s, int len) { if (s && *s && len != 0) { CAST_TDC(win, tdc); RCT rct; const bool noclip = !tdc.GetClippingBox(&rct); if (noclip || x < rct.right) { wxString str(s); if (len >= 0) str.Truncate(len); wxDC& dc = tdc.GetDC(); // Prima getto il DC ... const int delta = tdc.GetFontDelta(); // ... poi faccio la GetFontDelta! #ifdef LINUX if (tdc._dct.opaque_text) { RCT back; back.left = x; back.right = x + xvt_dwin_get_text_width(win, str, -1); back.top = y - delta; back.bottom = y; CAST_COLOR(tdc._dct.back_color, brush_color); wxBrush* brush = wxTheBrushList->FindOrCreateBrush(brush_color, wxSOLID); const wxBrush & old_brush = dc.GetBrush(); const wxPen & old_pen = dc.GetPen(); const wxRect rct = NormalizeRCT(&back); dc.SetBrush(*brush); dc.SetPen(*wxTRANSPARENT_PEN); dc.DrawRectangle(rct); dc.SetBrush(old_brush); dc.SetPen(old_pen); } #endif dc.DrawText(str, x, y-delta); } } } RCT* xvt_dwin_get_clip(WINDOW win, RCT* rct) { CAST_TDC(win, dc); dc.GetClippingBox(rct); return rct; } DRAW_CTOOLS* xvt_dwin_get_draw_ctools(WINDOW win, DRAW_CTOOLS *ctoolsp) { CAST_TDC(win, dc); memcpy(ctoolsp, &dc._dct, sizeof(DRAW_CTOOLS)); return ctoolsp; } XVT_FNTID xvt_dwin_get_font(WINDOW win) { CAST_TDC(win, dc); TFontId* pFont = new TFontId(dc._font); return pFont; } void xvt_dwin_get_font_metrics(WINDOW win, int *leadingp, int *ascentp, int *descentp) { CAST_DC(win, dc); const wxString str = "Mq"; int height, desc, lead; dc.GetTextExtent(str, NULL, &height, &desc, &lead); if (leadingp) *leadingp = lead; if (ascentp) *ascentp = height-lead-desc; if (descentp) *descentp = desc; } long xvt_dwin_get_font_size_mapped(WINDOW win) { CAST_WIN(win, dc); const wxFont& font = dc.GetFont(); int height = font.GetPointSize(); return height; } int xvt_dwin_get_text_width(WINDOW win, const char *s, int len) { int width = 0, height; if (s && *s && len != 0) { CAST_DC(win, dc); wxString str = s; if (len >= 0) str.Truncate(len); if (str.StartsWith("ABCDEFGH") || str.StartsWith("MMMMMMMM")) { const wxString emme('G', str.Length()); // Questa lettera cambia con le mode str = emme; } dc.GetTextExtent(str, &width, &height); } return width; } void xvt_dwin_invalidate_rect(WINDOW win, RCT* rctp) { CAST_WIN(win, w); if (rctp) { const wxRect rct = NormalizeRCT(rctp); w.Refresh(FALSE, &rct); } else { w.Refresh(FALSE); } } BOOLEAN xvt_dwin_is_update_needed(WINDOW win, RCT* rctp) { if (win != NULL_WIN && rctp != NULL) { if (win == PRINTER_WIN || win == SCREEN_WIN) return TRUE; CAST_WIN(win, w); const wxRect rect1 = NormalizeRCT(rctp); const wxRect rect2 = w.GetUpdateRegion().GetBox(); return RectIntersect(rect1, rect2); } return FALSE; } void xvt_dwin_scroll_rect(WINDOW win, RCT *rctp, int dh, int dv) { if (dh != 0 || dv != 0) { CAST_WIN(win, w); if (rctp != NULL) { wxRect rct = NormalizeRCT(rctp); if (rct.width > 0 && rct.height > 0) #ifdef WIN32 w.ScrollWindow(dh, dv, &rct); #else xvt_dwin_invalidate_rect(win, rctp); #endif } else w.ScrollWindow(dh, dv); } } void xvt_dwin_set_back_color(WINDOW win, COLOR color) { CAST_TDC(win, dc); dc._dct.back_color = color; dc.SetDirty(); } void xvt_dwin_set_cbrush(WINDOW win, CBRUSH* cbrush) { CAST_TDC(win, dc); memcpy(&dc._dct.brush, cbrush, sizeof(CBRUSH)); dc.SetDirty(); } void xvt_dwin_set_clip(WINDOW win, const RCT* rctp) { CAST_TDC(win, dc); dc.SetClippingBox(rctp); } void xvt_dwin_set_cpen(WINDOW win, CPEN* cpen) { CAST_TDC(win, dc); memcpy(&dc._dct.pen, cpen, sizeof(CPEN)); dc.SetDirty(); } void xvt_dwin_set_draw_ctools(WINDOW win, DRAW_CTOOLS* xct) { CAST_TDC(win, dc); memcpy(&dc._dct, xct, sizeof(DRAW_CTOOLS)); dc.SetDirty(); } void xvt_dwin_set_draw_mode(WINDOW win, DRAW_MODE mode) { CAST_TDC(win, dc); dc._dct.mode = mode; dc.SetDirty(); } void xvt_dwin_set_font(WINDOW win, XVT_FNTID font_id) { XVT_ASSERT(font_id != NULL); CAST_TDC(win, dc); const TFontId& font = *(const TFontId*)font_id; if (dc._font != font) { dc._font = font; dc.SetDirty(); } } void xvt_dwin_set_fore_color(WINDOW win, COLOR color) { CAST_TDC(win, dc); dc._dct.fore_color = color; dc.SetDirty(); } void xvt_dwin_set_std_cbrush(WINDOW win, long flag) { CBRUSH brush; brush.pat = PAT_SOLID; switch (flag) { case TL_BRUSH_BLACK: brush.color = COLOR_BLACK; break; case TL_BRUSH_WHITE: brush.color = COLOR_WHITE; break; default: SORRY_BOX(); break; } xvt_dwin_set_cbrush(win, &brush); } void xvt_dwin_set_std_cpen(WINDOW win, long flag) { CPEN pen; memset(&pen, 0, sizeof(CPEN)); pen.style = P_SOLID; pen.pat = PAT_SOLID; switch(flag) { case TL_PEN_BLACK : pen.color = COLOR_BLACK; break; case TL_PEN_DKGRAY: pen.color = COLOR_DKGRAY; break; case TL_PEN_GRAY : pen.color = COLOR_GRAY; break; case TL_PEN_LTGRAY: pen.color = COLOR_LTGRAY; break; case TL_PEN_WHITE : pen.color = COLOR_WHITE; break; case TL_PEN_HOLLOW: pen.pat = PAT_HOLLOW; break; case TL_PEN_RUBBER: pen.pat = PAT_RUBBER; break; default: SORRY_BOX(); break; } xvt_dwin_set_cpen(win, &pen); } void xvt_dwin_draw_line(WINDOW win, PNT pnt) { CAST_TDC(win, tdc); const wxPoint to(pnt.h, pnt.v); wxDC& dc = tdc.GetDC(); if (tdc._pnt != to) dc.DrawLine(tdc._pnt, to); dc.DrawPoint(to); tdc._pnt = to; } void xvt_dwin_update(WINDOW win) { CAST_WIN(win, w); w.Update(); } /////////////////////////////////////////////////////////// // Debug functions /////////////////////////////////////////////////////////// XVT_ERRSEV xvt_errmsg_get_sev_id(XVT_ERRMSG err) { return (XVT_ERRSEV)err; } /////////////////////////////////////////////////////////// // Fonts /////////////////////////////////////////////////////////// void xvt_font_copy(XVT_FNTID dest_font_id, XVT_FNTID src_font_id, XVT_FONT_ATTR_MASK mask) { XVT_ASSERT(dest_font_id && src_font_id && mask == XVT_FA_ALL); TFontId* dst = (TFontId*)dest_font_id; TFontId* src = (TFontId*)src_font_id; *dst = *src; } XVT_FNTID xvt_font_create(void) { TFontId* pFont = new TFontId; return (XVT_FNTID)pFont; } void xvt_font_deserialize(XVT_FNTID font_id, const char* buf) { // 01\\Courier\\0\\10\\WIN01/-13/0/0/0/400/0/0/0/0/1/2/1/49/Courier TFontId& font = *(TFontId*)font_id; char* s = strchr(buf, '/'); if (s == NULL) return; const int nSize = atoi(s+1); if (nSize > 0) font.SetPointSize(nSize); else font.SetPointSize(-nSize * 10 / 13); // Ignore 4 fields int i; for (i = 0; i < 4; i++) { s = strchr(s+1, '/'); if (s == NULL) return; } s++; const int nWeight = atoi(s); if (nWeight >= 600) font.SetMask(font.Mask() | XVT_FS_BOLD); s = strchr(s, '/'); if (s == NULL) return; const int nItalic = atoi(s+1); if (nItalic) font.SetMask(font.Mask() | XVT_FS_ITALIC); // Ignore 8 fields for (i = 0; i < 8; i++) { s = strchr(s+1, '/'); if (s == NULL) return; } font.SetFaceName(s+1); font.SetWin(NULL_WIN); } void xvt_font_destroy(XVT_FNTID font_id) { delete (TFontId*)font_id; } BOOLEAN xvt_font_get_family(XVT_FNTID font_id, char* buf, long max_buf) { const TFontId& font = *(TFontId*)font_id; strncpy(buf, font.FaceName(), max_buf); buf[max_buf-1] = '\0'; return TRUE; } BOOLEAN xvt_font_get_family_mapped(XVT_FNTID font_id, char* buf, long max_buf) { return xvt_font_get_family(font_id, buf, max_buf); } void xvt_font_get_metrics(XVT_FNTID font_id, int *leadingp, int *ascentp, int *descentp) { const TFontId& font = *(TFontId*)font_id; WINDOW win = font.Win(); if (win == NULL_WIN) win = TASK_WIN; CAST_DC(win, dc); const wxString str = "Mq"; int height, desc, lead; dc.GetTextExtent(str, NULL, &height, &desc, &lead, &font.Font(&dc, win)); if (leadingp) *leadingp = lead; if (ascentp) *ascentp = height-desc-lead; if (descentp) *descentp = desc; } BOOLEAN xvt_font_get_native_desc(XVT_FNTID font_id, char *buf, long max_buf) { long len = xvt_font_serialize(font_id, buf, max_buf); return len > 0; } long xvt_font_get_size(XVT_FNTID font_id) { return ((TFontId*)font_id)->PointSize(); } XVT_FONT_STYLE_MASK xvt_font_get_style(XVT_FNTID font_id) { return ((TFontId*)font_id)->Mask(); } WINDOW xvt_font_get_win(XVT_FNTID font_id) { return ((TFontId*)font_id)->Win(); } BOOLEAN xvt_font_is_mapped(XVT_FNTID font_id) { bool yes = ((TFontId*)font_id)->Win() != NULL_WIN; return yes; } void xvt_font_map(XVT_FNTID font_id, WINDOW win) { TFontId* pFont = (TFontId*)font_id; pFont->SetWin(win); } void xvt_font_map_using_default(XVT_FNTID font_id) { xvt_font_map(font_id, TASK_WIN); } void xvt_font_set_family(XVT_FNTID font_id, const char* family) { TFontId& font = *(TFontId*)font_id; font.SetFaceName(family); } void xvt_font_set_size(XVT_FNTID font_id, long size) { TFontId& font = *(TFontId*)font_id; font.SetPointSize(size); } void xvt_font_set_style(XVT_FNTID font_id, XVT_FONT_STYLE_MASK mask) { TFontId& font = *(TFontId*)font_id; font.SetMask(mask); } long xvt_font_serialize(XVT_FNTID font_id, char *buf, long max_buf) { // 01\\Courier\\0\\10\\WIN01/-13/0/0/0/400/0/0/0/0/1/2/1/49/Courier TFontId& font = *(TFontId*)font_id; const char* name = font.FaceName(); const int size = font.PointSize(); const int italic = (font.Mask() & XVT_FS_ITALIC) != 0; const int weight = 400; // Normal size wxString str; str = wxString::Format("01\\%s\\0\\%d\\WIN01/%d/%d/0/0/%d/0/0/0/0/0/0/0/0/%s", name, size, size, weight, italic, name); strncpy(buf, str, max_buf); buf[max_buf-1] = '\0'; return strlen(buf); } void xvt_font_unmap(XVT_FNTID font_id) { TFontId& font = *(TFontId*)font_id; font.SetWin(NULL_WIN); } /////////////////////////////////////////////////////////// // File system /////////////////////////////////////////////////////////// BOOLEAN xvt_fsys_build_pathname(char *mbs, const char *volname, const char *dirname, const char *leafroot, const char *leafext, const char* /* leafvers */) { #ifdef WIN32 _makepath(mbs, volname, dirname, leafroot, leafext); #else *mbs = '\0'; if (dirname && *dirname) strcpy(mbs, dirname); if (leafroot && *leafroot) { if (!wxEndsWithPathSeparator(mbs) && !wxIsPathSeparator(*leafroot)) strcat(mbs, "/"); strcat(mbs, leafroot); } if (leafext && *leafext) { if (*leafext != '.') strcat(mbs, "."); strcat(mbs, leafext); } #endif return TRUE; } BOOLEAN xvt_fsys_parse_pathname(const char *mbs, char *volname, char *dirname, char *leafroot, char *leafext, char *leafvers) { wxString volume, path, file, ext; wxFileName::SplitPath(mbs, &volume, &path, &file, &ext); if (volname) { strcpy(volname, volume); #ifdef WIN32 if (volname[0] != '\0' && volname[1] == '\0') strcat(volname, ":"); #endif } if (dirname) strcpy(dirname, path); if (leafroot) strcpy(leafroot, file); if (leafext) strcpy(leafext, ext); if (leafvers) strcpy(leafvers, ""); // TBI put here last change date/time? return TRUE; } BOOLEAN xvt_fsys_convert_dir_to_str(DIRECTORY *dirp, char *path, int sz_path) { wxStrncpy(path, dirp->path, sz_path); path[sz_path-1] = '\0'; return TRUE; } BOOLEAN xvt_fsys_convert_str_to_dir(const char *path, DIRECTORY *dirp) { if (dirp != NULL) strcpy(dirp->path, path); return dirp != NULL; } void xvt_fsys_get_default_dir(DIRECTORY *dirp) { if (_startup_dir == NULL) _startup_dir = new wxString(::wxGetCwd()); xvt_fsys_convert_str_to_dir(*_startup_dir, dirp); } BOOLEAN xvt_fsys_get_dir(DIRECTORY *dirp) { wxString str = ::wxGetCwd(); return xvt_fsys_convert_str_to_dir(str, dirp); } BOOLEAN xvt_fsys_is_removable_drive(const char* path) { #ifdef WIN32 if (path != NULL && path[0] == '\\' && path[1] == '\\') return FALSE; char drive[_MAX_DRIVE+1]; xvt_fsys_parse_pathname(path,drive,NULL,NULL,NULL,NULL); strcat(drive,"\\"); return GetDriveType(drive) == DRIVE_REMOVABLE; #else char dev[_MAX_PATH]; OsLinux_GetFileSys(path, dev, NULL, NULL); return strncmp(dev, "/dev/fd", 7) == 0; #endif } BOOLEAN xvt_fsys_is_network_drive(const char* path) { #ifdef WIN32 if (path != NULL && path[0] == '\\' && path[1] == '\\') return TRUE; char drive[_MAX_DRIVE+1]; xvt_fsys_parse_pathname(path,drive,NULL,NULL,NULL,NULL); strcat(drive,"\\"); return GetDriveType(drive) == DRIVE_REMOTE; #else return OsLinux_IsNetworkDrive(path); #endif } BOOLEAN xvt_fsys_is_fixed_drive(const char* path) { #ifdef WIN32 if (path != NULL && path[0] == '\\' && path[1] == '\\') return FALSE; char drive[_MAX_DRIVE+1]; xvt_fsys_parse_pathname(path,drive,NULL,NULL,NULL,NULL); strcat(drive,"\\"); return GetDriveType(drive) == DRIVE_FIXED; #else return !(xvt_fsys_is_network_drive(path) || xvt_fsys_is_removable_drive(path)); #endif } static unsigned long compute_disk_size(const char* path, bool tot, char unit) { #ifdef WIN32 char drive[_MAX_DRIVE+1]; xvt_fsys_parse_pathname(path, drive, NULL, NULL, NULL, NULL); strcat(drive, "/"); DWORD nSecPerClust, nBytePerSec, nFreeClust, nTotalClust; ::GetDiskFreeSpace(drive, &nSecPerClust, &nBytePerSec, &nFreeClust, &nTotalClust); __int64 nBytes = tot ? nTotalClust : nFreeClust; nBytes *= nSecPerClust; nBytes *= nBytePerSec; #else int64_t nBytes = OsLinux_GetDiskFreeSpace(path); #endif switch (unit) { case 'K': nBytes >>= 10; break; // Kilobytes case 'M': nBytes >>= 20; break; // Megabytes case 'G': nBytes >>= 30; break; // Gigabytes case 'T': nBytes >>= 40; break; // Terabytes default: break; } const unsigned long nMax = (unsigned long)(~0L); unsigned long nVal = nBytes > nMax ? nMax : (unsigned long)nBytes; return nVal; } unsigned long xvt_fsys_get_disk_size(const char* path, char unit) { return compute_disk_size(path, true, unit); } unsigned long xvt_fsys_get_disk_free_space(const char* path, char unit) { return compute_disk_size(path, false, unit); } BOOLEAN xvt_fsys_test_disk_free_space(const char* path, unsigned long filesize) { // Arrotonda per eccesso al Kilobyte unsigned long kb = filesize/1024+4; return kb <= xvt_fsys_get_disk_free_space(path, 'K'); } /////////////////////////////////////////////////////////// // File system /////////////////////////////////////////////////////////// SLIST xvt_fsys_list_files(char *type, char *pat, BOOLEAN dirs) { SLIST list = xvt_slist_create(); int flags = 0; if (dirs) { if (strcmp(type, DIR_TYPE) == 0) flags = wxDIR; } else flags = wxFILE; wxString f = ::wxFindFirstFile(pat, flags); while (!f.IsEmpty()) { #ifdef WIN32 if (f.StartsWith(".\\")) #else if (f.StartsWith("./")) #endif f = f.Mid(2); xvt_slist_add_at_elt(list, NULL, f, 0L); f = ::wxFindNextFile(); } return list; } static wxString _strSavedir; void xvt_fsys_restore_dir() { ::wxSetWorkingDirectory(_strSavedir); } void xvt_fsys_save_dir() { _strSavedir = ::wxGetCwd(); } BOOLEAN xvt_fsys_set_dir(DIRECTORY *dirp) { return ::wxSetWorkingDirectory(dirp->path); } /////////////////////////////////////////////////////////// // Images /////////////////////////////////////////////////////////// XVT_IMAGE xvt_image_capture(WINDOW win, const RCT* src) { wxRect r; if (src == NULL) { RCT rct; xvt_vobj_get_client_rect(win, &rct); r = NormalizeRCT(&rct); } else r = NormalizeRCT(src); wxBitmap bmp(r.GetWidth(), r.GetHeight()); CAST_DC(win, wdc); wxMemoryDC mdc; mdc.SelectObject(bmp); mdc.Blit(wxPoint(0,0), r.GetSize(), &wdc, r.GetPosition()); TXVT_IMAGE* i = new TXVT_IMAGE; i->Image() = bmp.ConvertToImage(); return (XVT_IMAGE)i; } XVT_IMAGE xvt_image_create(XVT_IMAGE_FORMAT format, short width, short height, long reserved) { TXVT_IMAGE* i = new TXVT_IMAGE; i->Image().Create(width, height); return (XVT_IMAGE)i; } void xvt_image_destroy(XVT_IMAGE image) { delete (TXVT_IMAGE*)image; } COLOR xvt_image_get_clut(XVT_IMAGE image, short index) { XVT_ASSERT(image != NULL); if (image) { const wxImage& bmp = ((const TXVT_IMAGE*)image)->Image(); if (bmp.HasPalette()) { const wxPalette& pal = bmp.GetPalette(); unsigned char r, g, b; pal.GetRGB(index, &r, &g, &b); return MAKE_COLOR(r, g, b); } } return COLOR_BLACK; } void xvt_image_get_dimensions(XVT_IMAGE image, short *width, short *height) { const wxImage& img = ((const TXVT_IMAGE*)image)->Image(); if (img.Ok()) { *width = img.GetWidth(); *height = img.GetHeight(); } else { *width = *height = 0; } } XVT_IMAGE_FORMAT xvt_image_get_format(XVT_IMAGE image) { const wxImage& img = ((const TXVT_IMAGE*)image)->Image(); return img.HasPalette() ? XVT_IMAGE_CL8 : XVT_IMAGE_RGB; } short xvt_image_get_ncolors(XVT_IMAGE image) { int n = 0; if (image) { const wxImage& bmp = ((const TXVT_IMAGE*)image)->Image(); if (bmp.HasPalette()) { const wxPalette& pal = bmp.GetPalette(); unsigned char r, g, b; for (n = 16; n < 256; n++) { if (!pal.GetRGB(n, &r, &g, &b)) break; } } } return n; } COLOR xvt_image_get_pixel(XVT_IMAGE image, short x, short y) { const wxImage& bmp = ((const TXVT_IMAGE*)image)->Image(); int r = bmp.GetRed(x, y); int g = bmp.GetGreen(x, y); int b = bmp.GetBlue(x, y); return MAKE_COLOR(r, g, b); } XVT_IMAGE xvt_image_read(const char* filenamep) { TXVT_IMAGE* i = NULL; #ifdef WIN32 const wxString name = filenamep; #else wxString name; if (isalpha(filenamep[0u])) { name = *_startup_dir; name += "/"; } name += filenamep; #endif if (::wxFileExists(name)) { i = new TXVT_IMAGE; i->Image().LoadFile(name); if (!i->Image().Ok()) { delete i; i = NULL; } } return (XVT_IMAGE)i; } XVT_IMAGE xvt_image_read_bmp(const char *filenamep) { return xvt_image_read(filenamep); // Very clever! } void xvt_image_set_clut(XVT_IMAGE image, short index, COLOR color) { wxImage& bmp = ((TXVT_IMAGE*)image)->Image(); if (bmp.HasPalette()) { const wxPalette& pal = bmp.GetPalette(); CAST_COLOR (color, c); unsigned char ri, gi, bi; pal.GetRGB(index, &ri, &gi, &bi); const int w = bmp.GetWidth(); const int h = bmp.GetHeight(); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { unsigned char r = bmp.GetRed(x, y); if (r != ri) continue; unsigned char g = bmp.GetGreen(x, y); if (g != gi) continue; unsigned char b = bmp.GetBlue(x, y); if (b != bi) continue; bmp.SetRGB(x, y, c.Red(), c.Green(), c.Blue()); } } } void xvt_image_set_ncolors(XVT_IMAGE image, short ncolors) { // SORRY_BOX(); } void xvt_image_set_pixel(XVT_IMAGE image, short x, short y, COLOR color) { wxImage& bmp = ((TXVT_IMAGE*)image)->Image(); CAST_COLOR (color, c); bmp.SetRGB(x, y, c.Red(), c.Green(), c.Blue()); } void xvt_image_transfer(XVT_IMAGE dstimage, XVT_IMAGE srcimage, RCT *dstrctp, RCT *srcrctp) { wxImage& dst = ((TXVT_IMAGE*)dstimage)->Image(); const wxRect rctDst = NormalizeRCT(dstrctp); const wxRect rctSrc = NormalizeRCT(srcrctp); wxMemoryDC dc; wxBitmap bmp(dst); dc.SelectObject(bmp); DrawImageOnDC(dc, (TXVT_IMAGE*)srcimage, rctDst, rctSrc); dst = bmp.ConvertToImage(); dc.SelectObject(wxNullBitmap); } /////////////////////////////////////////////////////////// // Memory management /////////////////////////////////////////////////////////// DATA_PTR xvt_mem_alloc(size_t size) { DATA_PTR ptr = (DATA_PTR)malloc(size); return ptr; } void xvt_mem_free(DATA_PTR p) { free(p); } DATA_PTR xvt_mem_realloc(DATA_PTR p, size_t size) { return (DATA_PTR)realloc(p, size); } DATA_PTR xvt_mem_rep(DATA_PTR dst, DATA_PTR src, unsigned int srclen, long reps) { XVT_ASSERT(dst != NULL || src != NULL); if (srclen == 1) memset(dst, *src, reps); else { for (long i = 0; i < reps; i++) memcpy(dst + i*srclen, src, srclen); } return dst; } DATA_PTR xvt_mem_zalloc(size_t size) { DATA_PTR ptr = xvt_mem_alloc(size); memset(ptr, 0, size); return ptr; } /////////////////////////////////////////////////////////// // Menu management /////////////////////////////////////////////////////////// int xvt_menu_count(const MENU_ITEM* m) { int n; for (n = 0; m[n].tag != 0; n++); return n; } // Funzione inventata MENU_ITEM* xvt_menu_duplicate_tree(const MENU_ITEM* m) { MENU_ITEM* TheMenu = NULL; if (m != NULL && m->tag > 0) { const int n = xvt_menu_count(m)+1; TheMenu = (MENU_ITEM*)xvt_mem_zalloc(sizeof(MENU_ITEM)*n); memcpy(TheMenu, m, n*sizeof(MENU_ITEM)); for (int i = 0; i < n; i++) { MENU_ITEM* mi = &TheMenu[i]; mi->text = xvt_str_duplicate(mi->text); mi->child = xvt_menu_duplicate_tree(mi->child); } } return TheMenu; } MENU_ITEM* xvt_menu_get_tree(WINDOW win) { MENU_ITEM* m = NULL; if (win == TASK_WIN) { TTaskWin& w = *(TTaskWin*)win; m = xvt_menu_duplicate_tree(w.GetMenuTree()); } else { CAST_TWIN(win, w); m = xvt_menu_duplicate_tree(w.GetMenuTree()); } return m; } BOOLEAN xvt_menu_popup(MENU_ITEM *menu_p, WINDOW win, PNT pos, XVT_POPUP_ALIGNMENT /* alignment */, MENU_TAG /* item */) { wxMenu menu; for (MENU_ITEM* mi = menu_p; mi != NULL && mi->tag != 0; mi++) { wxMenuItem* item = NULL; if (mi->separator) item = new wxMenuItem(&menu, wxID_SEPARATOR); else item = new wxMenuItem(&menu, mi->tag, mi->text, wxEmptyString, mi->checkable); menu.DoAppend(item); item->Enable(mi->enabled); // Fattibile solo dopo l'append if (mi->checkable) item->Check(mi->checked); } CAST_WIN(win, w); bool ok = w.PopupMenu(&menu, pos.h, pos.v); return ok; } static void TranslateMenu(wxMenu* pMenu, TRANSLATE_CALLBACK tc) { wxMenuItemList& list = pMenu->GetMenuItems(); for (unsigned i = 0; i < list.GetCount(); i++) { wxMenuItem* mi = list[i]; if (!mi->IsSeparator()) { const char* ita = mi->GetText(); const char* eng = tc(ita); mi->SetText(eng); wxMenu* pMenu = mi->GetSubMenu(); if (pMenu != NULL) TranslateMenu(pMenu, tc); } } } void xvt_menu_translate_tree(WINDOW win, TRANSLATE_CALLBACK tc) { if (win == TASK_WIN) { TTaskWin& w = *(TTaskWin*)win; wxMenuBar* pMenuBar = w.GetMenuBar(); if (pMenuBar != NULL) { for (int m = pMenuBar->GetMenuCount()-1; m >= 0; m--) { const char* ita = pMenuBar->GetLabelTop(m); const char* eng = tc(ita); pMenuBar->SetLabelTop(m, eng); wxMenu* pMenu = pMenuBar->GetMenu(m); TranslateMenu(pMenu, tc); } } } } void xvt_menu_set_font_sel(WINDOW win, XVT_FNTID font_id) { /* Ignored */ } static wxMenuItem* GetXvtMenuItem(WINDOW /* win */, MENU_TAG tag) { wxMenuBar* bar = ((TTaskWin*)_task_win)->GetMenuBar(); wxMenuItem* item = bar ? bar->FindItem(tag) : NULL; return item; } void xvt_menu_set_item_checked(WINDOW win, MENU_TAG tag, BOOLEAN check) { wxMenuItem* item = GetXvtMenuItem(win, tag); if (item) item->Check(check != 0); } void xvt_menu_set_item_enabled(WINDOW win, MENU_TAG tag, BOOLEAN enable) { wxMenuItem* item = GetXvtMenuItem(win, tag); if (item) item->Enable(enable != 0); } void xvt_menu_set_item_title(WINDOW win, MENU_TAG tag, char* text) { wxMenuItem* item = GetXvtMenuItem(win, tag); if (item) item->SetText(text); } void xvt_menu_set_tree(WINDOW win, MENU_ITEM* tree) { if (win == TASK_WIN) { TTaskWin& w = *(TTaskWin*)win; //occhio w.SetMenuTree(tree); } else { CAST_TWIN(win, w); w.SetMenuTree(tree); } } void xvt_menu_update(WINDOW win) { wxMenuBar* bar = ((TTaskWin*)_task_win)->GetMenuBar(); if (bar) bar->Refresh(); } /////////////////////////////////////////////////////////// // Palette management /////////////////////////////////////////////////////////// short xvt_palet_add_colors(XVT_PALETTE palet, COLOR *colorsp, short numcolors) { return 0; } short xvt_palet_add_colors_from_image(XVT_PALETTE palet, XVT_IMAGE image) { return 0; } XVT_PALETTE xvt_palet_create(XVT_PALETTE_TYPE type, XVT_PALETTE_ATTR reserved) { return NULL; } void xvt_palet_destroy(XVT_PALETTE palet) { SORRY_BOX(); } short xvt_palet_get_colors(XVT_PALETTE palet, COLOR *colorsp, short maxcolors) { return 0; } short xvt_palet_get_ncolors(XVT_PALETTE palet) { return 0; } int xvt_palet_get_tolerance(XVT_PALETTE p) { return 0; } void xvt_palet_set_tolerance(XVT_PALETTE p, int t) { SORRY_BOX(); } /////////////////////////////////////////////////////////// // Rectangles /////////////////////////////////////////////////////////// int xvt_rect_get_height(RCT *rctp) { return rctp->bottom - rctp->top; } int xvt_rect_get_width(RCT *rctp) { return rctp->right - rctp->left; } BOOLEAN xvt_rect_has_point(RCT *rctp, PNT pnt) { const wxRect rct = NormalizeRCT(rctp); return rct.Inside(pnt.h, pnt.v); } BOOLEAN xvt_rect_intersect(RCT *drctp, RCT *rctp1, RCT *rctp2) { const wxRect rect1 = NormalizeRCT(rctp1); const wxRect rect2 = NormalizeRCT(rctp2); BOOLEAN yes = RectIntersect(rect1, rect2); if (yes && drctp) { drctp->left = max(rect1.x, rect2.x); drctp->top = max(rect1.y, rect2.y); drctp->right = min(rect1.GetRight(), rect2.GetRight())+1; drctp->bottom = min(rect1.GetBottom(), rect2.GetBottom())+1; } return yes; } BOOLEAN xvt_rect_is_empty(const RCT *rct) { return rct == NULL || (rct->left==rct->right && rct->top==rct->bottom); } void xvt_rect_offset(RCT *rctp, short dh, short dv) { XVT_ASSERT(rctp != NULL); rctp->left += dh; rctp->top += dv; rctp->right += dh; rctp->bottom += dv; } void xvt_rect_set(RCT *rctp, short left, short top, short right, short bottom) { XVT_ASSERT(rctp != NULL); rctp->left = left; rctp->top = top; rctp->right = right; rctp->bottom = bottom; } void xvt_rect_set_empty(RCT *rctp) { XVT_ASSERT(rctp != NULL); rctp->right = rctp->left; rctp->bottom = rctp->top; } BOOLEAN xvt_rect_set_pos(RCT *rctp, PNT pos) { BOOLEAN ok = rctp != NULL; if (ok) { const short w = rctp->right-rctp->left; const short h = rctp->bottom-rctp->top; rctp->left = pos.h; rctp->top = pos.v; rctp->right = pos.h + w; rctp->bottom = pos.v + h; } return ok; } /////////////////////////////////////////////////////////// // Resource management /////////////////////////////////////////////////////////// void xvt_res_free_menu_tree(MENU_ITEM* tree) { XVT_ASSERT(tree != NULL); if (tree != NULL) { for (MENU_ITEM* item = tree; item->tag != 0; item++) { if (item->text) xvt_mem_free(item->text); if (item->child != NULL) xvt_res_free_menu_tree(item->child); } xvt_mem_free((DATA_PTR)tree); } } XVT_IMAGE xvt_res_get_image(int rid) { const wxString strFileName = ::GetResourceName("Image", rid); const bool ok = !strFileName.IsEmpty(); XVT_ASSERT(ok); return ok ? xvt_image_read(strFileName) : NULL; } static int SplitString(const wxString& str, wxArrayString& a) { const char* s = str; char* comma = ""; a.Clear(); while (comma) { comma = strchr(s, ','); if (comma) { *comma = '\0'; a.Add(s); *comma = ','; s = comma+1; } else a.Add(s); } return a.GetCount(); } static void FillMenuItem(const wxString& strValue, MENU_ITEM* mi) { wxArrayString a; const int n = SplitString(strValue, a); mi->tag = n > 0 ? atoi(a[0]) : 0; if (mi->tag > 0) { const wxString& str = a[1]; const int accelera = str.Find('&'); if (accelera >= 0) mi->mkey = str[accelera+1]; mi->text = xvt_str_duplicate(str); mi->enabled = n < 3 || (a[2].Find('D')<0); mi->checkable = n >= 3 && (a[2].Find('C')>=0); mi->checked = n >= 3 && (a[2].Find('c')>=0); } else { mi->tag = -1; mi->separator = TRUE; } } MENU_ITEM* xvt_res_get_menu(int rid) { wxFileConfig ini("", "", GetResourceIni()); const int MAX_MENU = 16; MENU_ITEM* TheMenu = (MENU_ITEM*)xvt_mem_zalloc(sizeof(MENU_ITEM)*MAX_MENU); wxString strName; if (rid >= 10000 && rid < 10100) { wxFileName::SplitPath(wxTheApp->argv[0], NULL, &strName, NULL); strName.MakeUpper(); strName = wxString::Format("/Menu_%s-%X", (const char *) strName.Left(3), (rid-1)%16); } else strName = wxString::Format("/Menu_%d", rid); ini.SetPath(strName); wxString strItem; for (int i = 0; i < MAX_MENU; i++) { MENU_ITEM* mi = &TheMenu[i]; strItem = wxString::Format("Item_%02d", i); if (ini.Read(strItem, &strName)) { FillMenuItem(strName, mi); mi = mi->child = (MENU_ITEM*)xvt_mem_zalloc(sizeof(MENU_ITEM)*MAX_MENU); for (int j = 0; j < MAX_MENU; j++, mi++) { strItem = wxString::Format("Item_%02d_%02d", i, j); if (ini.Read(strItem, &strName)) FillMenuItem(strName, mi); else break; } } else break; } if (TheMenu->tag == 0) { XVT_ASSERT(false); // Menu not found xvt_res_free_menu_tree(TheMenu); TheMenu = NULL; } return TheMenu; } char* xvt_res_get_str(int rid, char *s, int sz_s) { XVT_ASSERT(s != NULL && sz_s > 0); const wxString str = ::GetResourceName("String", rid); strncpy(s, str, sz_s); s[sz_s-1] = '\0'; return s; } /////////////////////////////////////////////////////////// // Scroll bars /////////////////////////////////////////////////////////// #define CAST_SCROLL(win, sb) XVT_ASSERT(win != NULL_WIN); wxScrollBar& sb = *(wxScrollBar*)win; #define CAST_SCROLL_TYPE(t, dir) const int dir = t == HSCROLL ? wxHORIZONTAL : wxVERTICAL; int xvt_sbar_get_pos(WINDOW win, SCROLL_TYPE t) { if (t == HSCROLL || t == VSCROLL) { CAST_WIN(win, w); CAST_SCROLL_TYPE(t, dir); return w.GetScrollPos(dir); } CAST_SCROLL(win, sb); return sb.GetThumbPosition(); } int xvt_sbar_get_proportion(WINDOW win, SCROLL_TYPE t) { if (t == HSCROLL || t == VSCROLL) { CAST_WIN(win, w); CAST_SCROLL_TYPE(t, dir); return w.GetScrollThumb(dir); } CAST_SCROLL(win, sb); return sb.GetThumbSize(); } void xvt_sbar_get_range(WINDOW win, SCROLL_TYPE t, int *minp, int *maxp) { *minp = 0; if (t == HSCROLL || t == VSCROLL) { CAST_WIN(win, w); CAST_SCROLL_TYPE(t, dir); *maxp = w.GetScrollRange(dir); } else { CAST_SCROLL(win, sb); *maxp = sb.GetRange(); } } void xvt_sbar_set_pos(WINDOW win, SCROLL_TYPE t, int pos) { if (t == HSCROLL || t == VSCROLL) { CAST_WIN(win, w); CAST_SCROLL_TYPE(t, dir); w.SetScrollPos(dir, pos); } else { CAST_SCROLL(win, sb); const int range = sb.GetRange(); const int size = sb.GetThumbSize(); sb.SetScrollbar(pos, size, range, size); } } void xvt_sbar_set_proportion(WINDOW win, SCROLL_TYPE t, int proportion) { if (t == HSCROLL || t == VSCROLL) { CAST_WIN(win, w); CAST_SCROLL_TYPE(t, dir); const int pos = w.GetScrollPos(dir); const int range = w.GetScrollRange(dir); w.SetScrollbar(dir, pos, proportion, range); } else { CAST_SCROLL(win, sb); const int pos = sb.GetThumbPosition(); const int range = sb.GetRange(); sb.SetScrollbar(pos, proportion, range, proportion); } } void xvt_sbar_set_range(WINDOW win, SCROLL_TYPE t, int min, int max) { XVT_ASSERT(min == 0); if (t == HSCROLL || t == VSCROLL) { CAST_WIN(win, w); CAST_SCROLL_TYPE(t, dir); const int pos = w.GetScrollPos(dir); const int size = w.GetScrollThumb(dir); w.SetScrollbar(dir, pos, size, max); } else { CAST_SCROLL(win, sb); const int pos = sb.GetThumbPosition(); const int size = sb.GetThumbSize(); sb.SetScrollbar(pos, size, max, size); } } /////////////////////////////////////////////////////////// // Window manager /////////////////////////////////////////////////////////// void xvt_scr_beep(void) { xvt_sys_beep(0); } WINDOW xvt_scr_get_focus_topwin(void) { WINDOW win = (WINDOW)_task_win->FindFocus(); return win; } WINDOW xvt_scr_get_focus_vobj(void) { return xvt_scr_get_focus_topwin(); } static void AddWinToList(SLIST list, WINDOW win) { if (win != NULL_WIN) { CAST_WIN(win, w); const char* title = w.GetTitle(); xvt_slist_add_at_elt(list, NULL, title, win); } } SLIST xvt_scr_list_wins() { SLIST list = xvt_slist_create(); _nice_windows.BeginFind(); //#if wxCHECK_VERSION(2,6,1) // for (wxHashTable_Node* node = _nice_windows.Next(); node; node = _nice_windows.Next()) //#else for (wxNode* node = _nice_windows.Next(); node; node = _nice_windows.Next()) //#endif { wxObject* pWin = node->GetData(); AddWinToList(list, (WINDOW)pWin); } return list; } void xvt_scr_set_busy_cursor() { xvt_win_set_cursor(TASK_WIN, CURSOR_WAIT); } void xvt_scr_set_focus_vobj(WINDOW win) { CAST_WIN(win, w); w.SetFocus(); } /////////////////////////////////////////////////////////// // String lists /////////////////////////////////////////////////////////// BOOLEAN xvt_slist_add_at_elt(SLIST list, SLIST_ELT e, const char *sx, long data) { const BOOLEAN ok = list != NULL; if (ok) { SLIST_ELT item = new SLIST_ITEM; item->str = xvt_str_duplicate(sx); item->data = data; item->next = NULL; SLIST_ELT last = NULL; // if (e != NULL) // Add at head by default (else at tail) // { for (SLIST_ELT i = list->head; i; i = (SLIST_ELT)i->next) { last = i; if (i == e) break; } // } if (last == NULL) { item->next = list->head; list->head = item; } else { item->next = last->next; last->next = item; } list->count++; } return ok; } int xvt_slist_count(SLIST list) { XVT_ASSERT(list != NULL); return list ? list->count : 0; } SLIST xvt_slist_create() { SLIST list = new xvtList; list->head = NULL; list->count = 0; return list; } void xvt_slist_destroy(SLIST list) { XVT_ASSERT(list != NULL); if (list) { SLIST_ELT obj = list->head; while (obj != NULL) { SLIST_ELT tokill = obj; xvt_mem_free(tokill->str); obj = (SLIST_ELT)tokill->next; delete tokill; } delete list; } } char* xvt_slist_get(SLIST list, SLIST_ELT e, long* datap) { XVT_ASSERT(list != NULL); if (e != NULL) { if (datap != NULL) *datap = e->data; return e->str; } return NULL; } long* xvt_slist_get_data(SLIST_ELT elt) { return elt != NULL ? &elt->data : NULL; } SLIST_ELT xvt_slist_get_first(SLIST list) { XVT_ASSERT(list != NULL); return list != NULL ? list->head : NULL; } SLIST_ELT xvt_slist_get_next(SLIST list, SLIST_ELT item) { XVT_ASSERT(list != NULL); return (SLIST_ELT)(item ? item->next : NULL); } /////////////////////////////////////////////////////////// // XVT Strings??? /////////////////////////////////////////////////////////// int xvt_str_compare_ignoring_case (const char* s1, const char* s2) { return wxStricmp(s1, s2); } char* xvt_str_duplicate(const char* str) { return str ? strdup(str) : NULL; // bleah! } BOOLEAN xvt_str_match(const char* mbs, const char *pat, BOOLEAN case_sensitive) { /* // Attualmente la wxString::Matches funziona solo con * e ? :-( wxString text = mbs; wxString pattern = pat; if (!case_sensitive) { text.MakeUpper(); pattern.MakeUpper(); } return text.Matches(pattern); */ // Uso la vecchia funzione implementata anticamente in agalib if (case_sensitive) return match(pat, mbs); wxString text = mbs; text.MakeUpper(); wxString pattern = pat; pattern.MakeUpper(); return match(pattern, text); } void xvt_str_make_upper(char* str) { #ifdef WIN32 _strupr(str); #else for (char * s = str; *s; s++) *s = toupper(*s); #endif } void xvt_str_make_lower(char* str) { for (char * s = str; *s; s++) *s = tolower(*s); } double xvt_str_fuzzy_compare (const char* s1, const char* s2) { return fstrcmp(s1, s2); } /////////////////////////////////////////////////////////// // XVT system calls (added by Guy) /////////////////////////////////////////////////////////// void xvt_sys_beep(int severity) { #ifdef WIN32 OsWin32_Beep(severity); #else wxBell(); #endif } BOOLEAN xvt_sys_get_host_name(char* name, int maxlen) { wxString str = wxGetHostName(); strncpy(name, str, maxlen); name[maxlen-1] = '\0'; return *name > '\0'; } BOOLEAN xvt_sys_get_user_name(char* name, int maxlen) { wxString str = wxGetUserId(); strncpy(name, str, maxlen); name[maxlen-1] = '\0'; return *name > '\0'; } /////////////////////////////////////////////////////////// // Process processing /////////////////////////////////////////////////////////// static bool __bChildRunning = false; class TIconizeTaskThread : public wxThread { protected: virtual ExitCode Entry(); public: TIconizeTaskThread(); }; wxThread::ExitCode TIconizeTaskThread::Entry() { Sleep(500); if (__bChildRunning) // Il programma e' ancora attivo { wxFrame* frame = (wxFrame*)_task_win; frame->Iconize(); } return 0; } TIconizeTaskThread::TIconizeTaskThread() { Create(); SetPriority(WXTHREAD_MIN_PRIORITY); Run(); } long xvt_sys_execute(const char* cmdline, BOOLEAN sync, BOOLEAN iconizetask) { long exitcode = 0; wxString cmd(cmdline); #ifdef LINUX if (isalpha(cmd[0u])) cmd = "./" + cmd; #endif if (sync) { if (iconizetask) { wxEnableTopLevelWindows(FALSE); // ((wxFrame*)_task_win)->Iconize(); TIconizeTaskThread* it; it = new TIconizeTaskThread(); __bChildRunning = true; exitcode = wxExecute(cmd, wxEXEC_SYNC); __bChildRunning = false; wxFrame* frame = (wxFrame*)_task_win; if (frame->IsIconized()) frame->Restore(); wxEnableTopLevelWindows(TRUE); frame->Raise(); } else exitcode = wxExecute(cmd, wxEXEC_SYNC); } else exitcode = wxExecute(cmd, wxEXEC_ASYNC); return exitcode; } long xvt_sys_execute_in_window(const char* cmdline, WINDOW win) { long inst = xvt_sys_execute(cmdline, FALSE, FALSE); if (inst > 0) #ifdef WIN32 OsWin32_PlaceProcessInWindow(inst, "", xvt_vobj_get_attr(ATTR_NATIVE_WINDOW, win)); #else OsLinux_PlaceProcessInWindow(inst, "", xvt_vobj_get_attr(ATTR_NATIVE_WINDOW, win)); #endif return inst; } BOOLEAN xvt_sys_goto_url(const char* url, const char* action) { #ifdef WIN32 return OsWin32_GotoUrl(url, action); #else SORRY_BOX(); // TBI return FALSE; #endif } BOOLEAN xvt_sys_dongle_server_is_running() { wxSingleInstanceChecker sic("Authorization"); BOOLEAN ok = sic.IsAnotherRunning(); #ifdef WIN32 if (!ok) // Testo anche Frontend! ok = ::GlobalFindAtom("DONGLE_SERVER_ATOM") != 0; #endif return ok; } int xvt_sys_get_profile_string(const char* file, const char* paragraph, const char* name, const char* defval, char* value, int maxsize) { #ifdef WIN32 int len = ::GetPrivateProfileString(paragraph, name, defval, value, maxsize, file); #else wxFileConfig ini("", "", file, "", wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_RELATIVE_PATH); wxString path; path << "/" << paragraph; ini.SetPath(path); int len = 0; wxString val; if (!ini.Read(name, &val)) val = defval; len = val.Length(); if (value) { wxStrncpy(value, val, maxsize); value[maxsize-1] = '\0'; } #endif return len; } BOOLEAN xvt_sys_set_profile_string(const char* file, const char* paragraph, const char* name, const char* value) { #ifdef WIN32 return ::WritePrivateProfileString(paragraph, name, value, file); #else wxFileConfig ini("", "", file, "", wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_RELATIVE_PATH); ini.SetUmask(0x0); wxString path; path << "/" << paragraph; ini.SetPath(path); return ini.Write(name, value); #endif } BOOLEAN xvt_sys_find_editor(const char* file, char* editor) { BOOLEAN ok = FALSE; #ifdef WIN32 const wxString e = OsWin32_File2App(file); #else const wxString e = OsLinux_File2App(file); #endif ok = !e.IsEmpty(); if (ok && editor != NULL) strcpy(editor, e); return ok; } unsigned int xvt_sys_load_icon(const char* file) { unsigned int id = 0; wxIcon* icon = NULL; wxString str = file; str.MakeLower(); if (str.Find(".ico") > 0) icon = new wxIcon(file, wxBITMAP_TYPE_ICO); else { #ifdef WIN32 WXHICON hicon = (WXHICON)OsWin32_LoadIcon(file); if (hicon) { icon = new wxIcon; icon->SetHICON(hicon); } #else icon = new wxIcon; // icon = new wxIcon(wxICON(file)); //verificare #endif } if (icon != NULL) { for (id = 60001; ; id++) { wxIcon* ico = (wxIcon*)_nice_icons.Get(id); if (ico == NULL) { _nice_icons.Put(id, icon); break; } else { #ifdef WIN32 if (ico->GetHICON() == icon->GetHICON()) // C'e' gia' #else if (ico == icon) // C'e' gia' #endif { delete icon; break; } } } } return id; } int xvt_sys_get_session_id() { #ifdef WIN32 return OsWin32_GetSessionId(); #else return OsLinux_GetSessionId(); #endif } unsigned long xvt_sys_get_free_memory() { unsigned long mem = ::wxGetFreeMemory(); return mem; } unsigned long xvt_sys_get_free_memory_kb() { unsigned long mem = xvt_sys_get_free_memory(); return mem / 1024; // Arrotondo per difetto } int xvt_sys_get_os_version() { int os = 0; int major, minor; switch (::wxGetOsVersion(&major, &minor)) { #ifdef WIN32 case wxWIN95: os = minor == 0 ? XVT_WS_WIN_95 : XVT_WS_WIN_98; break; case wxWINDOWS_NT: os = XVT_WS_WIN_NT; if (OsWin32_IsWindowsServer()) os = XVT_WS_WIN_SERVER; break; #else case wxGTK: os = XVT_WS_LINUX; break; #endif default: break; } return os; } void xvt_sys_sleep(unsigned long msec) { wxThread::Sleep(msec); } BOOLEAN xvt_sys_test_network_version() { #ifdef WIN32 if (xvt_sys_get_os_version() == XVT_WS_WIN_95) return OsWin32_TestNetworkVersion(); #endif return TRUE; } /////////////////////////////////////////////////////////// // XVT system calls (added by Alex) /////////////////////////////////////////////////////////// void xvt_sys_searchenv(const char * filename, const char * varname, char * pathname) { #ifdef WIN32 _searchenv(filename, varname, pathname); #else const char * value = getenv(varname); if (value) { char path_list[4096]; strcpy(path_list, value); for (const char* s = path_list; *s; ) { char* s1 = strchr(s, ';'); if (s1 != NULL) *s1 = '\0'; xvt_fsys_build_pathname(pathname, NULL, s, filename, NULL, NULL); if (xvt_fsys_file_exists(pathname)) break; if (s1 != NULL) s = s1 + 1; else break; } } else *pathname = '\0'; #endif } BOOLEAN xvt_fsys_access(const char *pathname, int mode) { wxString str = ::wxGetCwd(); return access(pathname, mode) == -1 ? errno : 0; } BOOLEAN xvt_fsys_file_exists(const char *pathname) { return wxFileExists(pathname); } BOOLEAN xvt_fsys_mkdir(const char *pathname) { if (wxDirExists(pathname)) return TRUE; return wxMkdir(pathname); } BOOLEAN xvt_fsys_rmdir(const char *pathname) { if (wxDirExists(pathname)) return TRUE; return wxRmdir(pathname); } BOOLEAN xvt_fsys_removefile(const char *pathname) { return wxRemoveFile(pathname); } /////////////////////////////////////////////////////////// // Timers /////////////////////////////////////////////////////////// long xvt_timer_create(WINDOW win, long interval) { CAST_TWIN(win, w); if (w._timer == NULL) { w._timer = new wxTimer(&w, TIMER_ID); w._timer->Start(interval); } return win; } void xvt_timer_destroy(long id) { if (id > 0L) { CAST_TWIN(id, w); wxTimer*& t = w._timer; if (t != NULL) { t->Stop(); delete t; t = NULL; } } } /////////////////////////////////////////////////////////// // Visual objects /////////////////////////////////////////////////////////// void xvt_vobj_destroy(WINDOW win) { if (win != PRINTER_WIN) { if (_TheCaret.Owner() == win) _TheCaret.Kill(); if (_nice_windows.Get(win) != NULL) { CAST_TWIN(win, w); w.Close(true); GetTDCMapper().DestroyTDC(win); } #ifdef DBG else XVT_ASSERT(FALSE); // Happens to list box windows #endif } GetTDCMapper().DestroyTDC(win); } long xvt_vobj_get_attr(WINDOW win, long data) { long ret = 0L; switch(data) { case ATTR_APP_CTL_COLORS: { XVT_COLOR_COMPONENT* xcc = (XVT_COLOR_COMPONENT*)xvt_mem_zalloc(sizeof(XVT_COLOR_COMPONENT)*6); xcc[0].type = XVT_COLOR_FOREGROUND; xcc[0].color = MAKE_XVT_COLOR(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT)); xcc[1].type = XVT_COLOR_BACKGROUND; xcc[1].color = MAKE_XVT_COLOR(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)); xcc[2].type = XVT_COLOR_CAPTIONLT; xcc[2].color = MAKE_XVT_COLOR(wxSystemSettings::GetColour(wxSYS_COLOUR_ACTIVECAPTION)); xcc[3].type = XVT_COLOR_CAPTIONDK; xcc[3].color = MAKE_XVT_COLOR(wxSystemSettings::GetColour(wxSYS_COLOUR_INACTIVECAPTION)); xcc[4].type = XVT_COLOR_CAPTIONTEXT; xcc[4].color = MAKE_XVT_COLOR(wxSystemSettings::GetColour(wxSYS_COLOUR_CAPTIONTEXT)); xcc[5].type = XVT_COLOR_NULL; xcc[5].color = 0; ret = (long)xcc; } break; case ATTR_FRAME_WIDTH: #ifdef LINUX ret = 8; //verificare not impl #else ret = wxSystemSettings::GetMetric(wxSYS_FRAMESIZE_X); #endif break; case ATTR_FRAME_HEIGHT: #ifdef LINUX ret = 8; //verificare not impl #else ret = wxSystemSettings::GetMetric(wxSYS_FRAMESIZE_Y); #endif break; case ATTR_MENU_HEIGHT: ret = wxSystemSettings::GetMetric(wxSYS_MENU_Y); break; case ATTR_TITLE_HEIGHT: #ifdef LINUX ret = 32; //verificare not impl #else ret = wxSystemSettings::GetMetric(wxSYS_CAPTION_Y); #endif break; case ATTR_CTL_VERT_SBAR_WIDTH: ret = wxSystemSettings::GetMetric(wxSYS_VSCROLL_X); break; case ATTR_CTL_HORZ_SBAR_HEIGHT: ret = wxSystemSettings::GetMetric(wxSYS_HSCROLL_Y); break; case ATTR_DISPLAY_TYPE: switch (::wxDisplayDepth()) { case 1: ret = XVT_DISPLAY_MONO; break; case 4: ret = XVT_DISPLAY_COLOR_16; break; case 8: ret = XVT_DISPLAY_COLOR_256; break; default: ret = XVT_DISPLAY_DIRECT_COLOR; break; } break; case ATTR_ERRMSG_HANDLER: ret = (long)_error_handler; break; case ATTR_NATIVE_GRAPHIC_CONTEXT: SORRY_BOX(); // Obsoleto e non piu' usato break; case ATTR_NATIVE_WINDOW: if (_nice_windows.Get(win) != NULL) { #ifdef WIN32 CAST_WIN(win, w); ret = (long)w.GetHandle(); #else ret = win; #endif } break; case ATTR_SCREEN_HEIGHT: ret = wxSystemSettings::GetMetric(wxSYS_SCREEN_Y); break; case ATTR_SCREEN_WIDTH: ret = wxSystemSettings::GetMetric(wxSYS_SCREEN_X); break; case ATTR_SCREEN_WINDOW: ret = 882L; // Scelta arbitraria ma accettabile break; case ATTR_SPEECH_MODE: ret = m_nSpeechMode; break; case ATTR_TASK_WINDOW: ret = long(_task_win); break; case ATTR_PRINTER_WINDOW: ret = 883L; // Scelta arbitraria ma accettabile break; case ATTR_WIN_INSTANCE: ret = 0; break; case ATTR_WIN_OPENFILENAME_HOOK: ret = 0; break; case ATTR_WIN_PM_DRAWABLE_TWIN: ret = TRUE; break; default: SORRY_BOX(); break; } return ret; } RCT* xvt_vobj_get_client_rect(WINDOW win, RCT *rctp) { XVT_ASSERT(rctp != NULL); int l, h; if (win != NULL_WIN) { if (win == PRINTER_WIN) { l = h = 6000; // circa A4 height } else if (win == SCREEN_WIN) { l = wxSystemSettings::GetMetric(wxSYS_SCREEN_X); h = wxSystemSettings::GetMetric(wxSYS_SCREEN_Y) - 32; // Puerile tentativo di escludere la task bar } else { CAST_WIN(win, w); w.GetClientSize(&l, &h); } } else // NULL_WIN = schermo intero { l = wxSystemSettings::GetMetric(wxSYS_SCREEN_X); h = wxSystemSettings::GetMetric(wxSYS_SCREEN_Y); } rctp->left = rctp->top = 0; rctp->right = l; rctp->bottom = h; return rctp; } long xvt_vobj_get_data(WINDOW win) { CAST_TWIN(win, w); return w._app_data; } RCT* xvt_vobj_get_outer_rect(WINDOW win, RCT *rctp) { XVT_ASSERT(rctp != NULL); CAST_WIN(win, w); const wxRect rct = w.GetRect(); rctp->left = rct.x; rctp->top = rct.y; rctp->right = rct.x + rct.width; rctp->bottom = rct.y + rct.height; return rctp; } XVT_PALETTE xvt_vobj_get_palet(WINDOW win) { return NULL; } WINDOW xvt_vobj_get_parent(WINDOW win) { if (win == TASK_WIN) return NULL_WIN; CAST_WIN(win, w); return (WINDOW)w.GetParent(); } char* xvt_vobj_get_title(WINDOW win, char *title, int sz_title) { CAST_WIN(win, w); strncpy(title, w.GetTitle(), sz_title); title[sz_title-1] = '\0'; return title; } WIN_TYPE xvt_vobj_get_type(WINDOW win) { if (win == TASK_WIN) return W_TASK; if (win == SCREEN_WIN) return W_SCREEN; if (win == PRINTER_WIN) return W_PRINT; CAST_TWIN(win, w); return w._type; } BOOLEAN xvt_vobj_is_focusable(WINDOW win) { return win != NULL_WIN && win != PRINTER_WIN; } void xvt_vobj_maximize(WINDOW win) { wxFrame* pMain = (wxFrame*)_task_win; if (win != (WINDOW)pMain) { CAST_WIN(win, w); int width, height; pMain->GetClientSize(&width, &height); w.SetSize(0, 0, width, height); } else pMain->Maximize(); } void xvt_vobj_minimize(WINDOW win) { wxFrame* pMain = (wxFrame*)_task_win; if (win == (WINDOW)pMain) pMain->Iconize(); else SORRY_BOX(); } void xvt_vobj_move(WINDOW win, const RCT* rctp) { CAST_WIN(win, w); wxRect rct = NormalizeRCT(rctp); w.Move(rct.x, rct.y); w.SetClientSize(rct.width, rct.height); } void xvt_vobj_raise(WINDOW win) { CAST_WIN(win, w); w.Raise(); } void xvt_vobj_set_attr(WINDOW win, long data, long value) { switch(data) { case ATTR_ERRMSG_HANDLER: _error_handler = (XVT_ERRMSG_HANDLER)value; break; case ATTR_EVENT_HOOK: SORRY_BOX(); break; // TBI?: Native events hook! case ATTR_WIN_PM_DRAWABLE_TWIN: break; // Ignored: Always TRUE case ATTR_WIN_PM_TWIN_STARTUP_RCT: _startup_rect = *(RCT*)value; break; case ATTR_WIN_PM_TWIN_STARTUP_STYLE: break; // TBI case ATTR_SPEECH_MODE: xvt_dm_enable_speech(value); break; default: SORRY_BOX(); break; } } void xvt_vobj_set_data(WINDOW win, long AppData) { CAST_TWIN(win, w); w._app_data = AppData; } void xvt_vobj_set_enabled(WINDOW win, BOOLEAN enabled) { CAST_WIN(win, w); w.Enable(enabled != 0); } void xvt_vobj_set_palet(WINDOW win, XVT_PALETTE palet) { // Do not implement! } void xvt_vobj_set_title(WINDOW win, const char* title) { CAST_WIN(win, w); w.SetTitle(title); } void xvt_vobj_set_visible(WINDOW win, BOOLEAN show) { CAST_WIN(win, w); w.Show(show != 0); } void xvt_vobj_translate_points(WINDOW from_win, WINDOW to_win, PNT *pntp, int npnts) { XVT_ASSERT(from_win != NULL_WIN && to_win != NULL_WIN); XVT_ASSERT(pntp != NULL && npnts > 0); CAST_WIN(from_win, w1); CAST_WIN(to_win, w2); for (int i = 0; i < npnts; i++) { int x = pntp[i].h; int y = pntp[i].v; w1.ClientToScreen(&x, &y); w2.ScreenToClient(&x, &y); pntp[i].h = x; pntp[i].v = y; } } /////////////////////////////////////////////////////////// // Real windows /////////////////////////////////////////////////////////// WINDOW xvt_win_create(WIN_TYPE wtype, const RCT* rct_p, const char* title, int menu_rid, WINDOW parent, long win_flags, EVENT_MASK mask, EVENT_HANDLER eh, long app_data) { XVT_ASSERT(rct_p != NULL); const wxString caption = title; const wxPoint pos(rct_p->left, rct_p->top); const wxSize size(rct_p->right-rct_p->left, rct_p->bottom-rct_p->top); long style = wxCLIP_CHILDREN | wxCLIP_SIBLINGS; if (win_flags & WSF_VSCROLL) style |= wxVSCROLL; if (win_flags & WSF_HSCROLL) style |= wxHSCROLL; TwxWindow* w = NULL; switch (wtype) { case W_DOC: if (!caption.IsEmpty()) style |= wxSYSTEM_MENU; break; case W_PLAIN: // style |= wxBORDER; // Non attivare MAI il bordo! if (win_flags & WSF_TRANSPARENT) style |= wxTRANSPARENT_WINDOW; break; default: SORRY_BOX(); break; } if (parent == SCREEN_WIN) parent = NULL; w = new TwxWindow((wxWindow*)parent, -1, caption, pos, size, style); w->_type = wtype; w->_app_data = app_data; #if wxCHECK_VERSION(2,6,1) w->SetBackgroundStyle(wxBG_STYLE_CUSTOM); // Lo sfondo viene disegnato nella OnPaint #endif #ifdef WIN32 OsWin32_SetCaptionStyle(w->GetHWND(), wtype == W_DOC); #else OsLinux_SetCaptionStyle((wxWindow*)w, style); #endif if (menu_rid > 0 && menu_rid != 8000) // 8000 = NULL_MENU_RID { MENU_ITEM* mi = xvt_res_get_menu(menu_rid); if (mi) { w->SetMenuTree(mi); xvt_res_free_menu_tree(mi); } } if (style & wxHSCROLL) w->SetScrollbar(wxHORIZONTAL, 0, 1, 100); if (style & wxVSCROLL) w->SetScrollbar(wxVERTICAL, 0, 1, 100); //xvt_vobj_move((WINDOW)w, rct_p); // Sembra inutile if (win_flags & WSF_DISABLED) w->Disable(); else w->Enable(); if (win_flags & WSF_INVISIBLE) w->Hide(); else w->Show(); // Non dovrebbe mai succedere nel nostro caso // Accetta messaggi solo da ora! w->_eh = eh; EVENT e; memset(&e, 0, sizeof(e)); e.type = E_CREATE; // Serve a poco, ma fa' lo stesso eh((WINDOW)w, &e); return (WINDOW)w; } long xvt_win_dispatch_event(WINDOW win, EVENT* event_p) { XVT_ASSERT(event_p != NULL); CAST_TWIN(win, w); return w._eh(win, event_p); } void xvt_win_post_event(WINDOW win, EVENT* event_p) { // Per ora funziona solo con la task window XVT_ASSERT(win == (WINDOW)_task_win && event_p != NULL); switch (event_p->type) { case E_COMMAND: { wxCommandEvent e(wxEVT_COMMAND_MENU_SELECTED, event_p->v.cmd.tag); e.SetEventObject(_task_win); wxPostEvent(_task_win, e); } break; default: SORRY_BOX(); break; } } void xvt_win_release_pointer(void) { if (_mouse_trapper != NULL) { // cap SHOULD be equal to _mouse_trapper :-) wxWindow* cap = _mouse_trapper->GetCapture(); if (cap != NULL) cap->ReleaseMouse(); _mouse_trapper = NULL; } } void xvt_win_set_caret_size(WINDOW win, int width, int height) { _TheCaret.SetSize(width, height); } void xvt_win_set_caret_pos(WINDOW win, PNT p) { _TheCaret.SetPos(p.h, p.v-1); } void xvt_win_set_caret_visible(WINDOW win, BOOLEAN on) { _TheCaret.Show(win, on != 0); } void xvt_win_set_cursor(WINDOW win, CURSOR cursor) { CAST_WIN(win, w); wxCursor* cur = wxSTANDARD_CURSOR; // Dummy initilization switch (cursor) { case CURSOR_ARROW: cur = wxSTANDARD_CURSOR; break; case CURSOR_CROSS: cur = wxCROSS_CURSOR; break; case CURSOR_WAIT : cur = wxHOURGLASS_CURSOR; break; default: cur = GetCursorResource(cursor); break; // Always succeeds } w.SetCursor(*cur); } void xvt_win_set_handler(WINDOW win, EVENT_HANDLER eh) { if (win == (WINDOW)_task_win) { _task_win_handler = eh; } else { CAST_TWIN(win, w); w._eh = eh; } } void xvt_win_trap_pointer(WINDOW win) { CAST_WIN(win, w); xvt_win_release_pointer(); w.CaptureMouse(); _mouse_trapper = &w; } /////////////////////////////////////////////////////////// // Status bar /////////////////////////////////////////////////////////// const char* statbar_set_title(WINDOW win, const char* text) { XVT_ASSERT(win == TASK_WIN); wxFrame& w = *(wxFrame*)win; if (text == NULL) text = _strDefaultStatbarText; char* tab = strchr(text, '\t'); if (tab) { w.SetStatusText(tab+1, 1); *tab = '\0'; w.SetStatusText(text); *tab = '\t'; } else w.SetStatusText(text); return text; } const char* statbar_set_default_title(WINDOW win, const char *text) { _strDefaultStatbarText = text; return statbar_set_title(win, _strDefaultStatbarText); } XVT_FNTID statbar_set_fontid(WINDOW win, XVT_FNTID fontid) { return fontid; // TBI??? } XVT_FNTID statbar_get_fontid(WINDOW win, XVT_FNTID fontid) { return fontid; // VERIFICARE } WINDOW statbar_create(int cid, int left, int top, int right, int bottom, int prop_count, char **prop_list, WINDOW parent_win, int parent_rid, long parent_flags, char *parent_class) { XVT_ASSERT(parent_win == TASK_WIN); TTaskWin& w = *(TTaskWin*)_task_win; w.CreateStatusBar(2); w.GetStatusBar()->Show(); wxSize sz = w.GetClientSize(); int widths[2]; widths[0] = -1; widths[1] = sz.x / 4; w.SetStatusWidths(2, widths); return (WINDOW)&w; }