#include "wxinc.h" #include "xvt.h" #include "statbar.h" #include "agasys.h" #include "fstrcmp.h" #include "matche.h" #include "xvtart.h" #include "xvtwin.h" #include #include #include #include #include #include #include #include #include #include #include #include #if wxCHECK_VERSION(2,9,0) #include #else #include #endif #ifdef __WXMSW__ #include "oswin32.h" #include "XFont.h" #else #include #include #include "oslinux.h" #include #endif #define XVT_ASSERT(test) _AssertBox((test), __FUNCTION__, __FILE__, __LINE__) wxWindow* _mouse_trapper = NULL; RCT _startup_rect = { 0,0,0,0 }; long _startup_style = 0; wxString _startup_dir; wxString _strDefaultStatbarText; wxString _appl_name; wxString _appl_version; wxLocale* _locale = NULL; static XVT_ERRMSG_HANDLER _error_handler = NULL; const wxString& _GetAppTitle() { return _appl_name; } void _AssertBox(bool test, const char* func, const char* file, int line) { if (!test) { bool display = (_error_handler == NULL) || (_error_handler(SEV_FATAL, NULL) == FALSE); if (display) { wxString strMessage; strMessage.Printf("Sorry, the application passed some invalid parameters to\n" "function %s in file %s at line %d.", func, file, line); xvt_dm_post_error(strMessage); } } } /////////////////////////////////////////////////////////// // XVT /////////////////////////////////////////////////////////// void xvt_app_allow_quit(void) { wxTheApp->ExitMainLoop(); // Già lo fa la destroy } XVTDLL void xvt_app_pre_create(void) { DIRECTORY dir; xvt_fsys_get_default_dir(&dir); // Init Startup Directory wxString strResPath = dir.path; strResPath += "/res"; _locale = new wxLocale(wxLANGUAGE_DEFAULT); // wxLANGUAGE_ITALIAN _locale->AddCatalogLookupPathPrefix(strResPath); _locale->AddCatalog("wxstd", wxLanguage(_locale->GetLanguage()), NULL); ::wxInitAllImageHandlers(); xvtart_Init(); #ifdef __WXMSW__ if (::wxDisplayDepth() >= 32 && wxTheApp->GetComCtl32Version() >= 600) wxSystemOptions::SetOption(wxT("msw.remap"), 2); else wxSystemOptions::SetOption(wxT("msw.remap"), 0); #endif #ifdef SPEECH_API xvt_dm_enable_speech(0xFF); #endif } void xvt_app_create(int WXUNUSED(argc), char** WXUNUSED(argv), unsigned long WXUNUSED(flags), EVENT_HANDLER eh, XVT_CONFIG* config) { _task_win_handler = eh; _appl_name = config->appl_name; const wxString title = config->taskwin_title; wxPoint pos = wxDefaultPosition; wxSize size = wxDefaultSize; long style = wxDEFAULT_FRAME_STYLE; wxWindow* pParent = NULL; bool bCanChangeFirm = true; #ifdef __WXMSW__ HWND hwndParent = (HWND)OsWin32_FindMenuContainer(); if (hwndParent != NULL) { pParent = new wxWindow; pParent->AssociateHandle(hwndParent); const wxSize szWin = pParent->GetSize(); const wxSize szCli = pParent->GetClientSize(); xvt_rect_set(&_startup_rect, 0, 0, szWin.x, szWin.y); style = wxSYSTEM_MENU; // Lo stile si riduce al minimo: niente cornici if ((szWin.y - szCli.y) > 2) // Sposto la finestra in modo da coprire il menu del padre _startup_rect.top -= xvt_vobj_get_attr(NULL_WIN, ATTR_MENU_HEIGHT); bCanChangeFirm = false; // In ogni caso NON posso piu' cambiare ditta } #endif 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 __WXMSW__ style |= wxMAXIMIZE; #else style &= ~wxMAXIMIZE; const wxRect rect = wxGetClientDisplayRect(); pos = rect.GetPosition(); size = rect.GetSize(); #endif } if (_startup_style & WSF_NO_TASKBAR) style |= wxFRAME_NO_TASKBAR; _task_win = new TTaskWin(ICON_RSRC, title, pos, size, style); _task_win->SetBackgroundStyle(wxBG_STYLE_CUSTOM); // Lo sfondo viene disegnato nella OnPaint _nice_windows.Put((WINDOW)_task_win, _task_win); if (pParent != NULL) { _task_win->Reparent(pParent); pParent->DissociateHandle(); pParent = NULL; } wxMenu* Menus[3]; wxString Title[3]; Title[0] = "&File"; Menus[0] = new wxMenu; if (bCanChangeFirm) { 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]->Append(M_FILE_PREVIEW, "&Anteprima"); 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] = "&?"; Menus[2] = new wxMenu; Menus[2]->Append(M_HELP_CONTENTS, "&Sommario"); Menus[2]->Append(M_HELP_ONCONTEXT, "&Aiuto contestuale"); Menus[2]->AppendSeparator(); Menus[2]->Append(M_FILE_ABOUT, "&Informazioni"); wxMenuBar* pMenubar = new wxMenuBar(3, Menus, Title); _task_win->SetMenuBar(pMenubar); if (style & wxMAXIMIZE) _task_win->Maximize(); _task_win->Show(); _task_win->Raise(); 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 xvt_app_process_pending_events(); } a->ExitMainLoop(); // Non entrare nel main loop di wxWidgets } void xvt_app_destroy(void) { wxTheApp->ExitMainLoop(); if (_task_win != NULL) _task_win->Destroy(); #ifdef SPEECH_API xvt_dm_enable_speech(0x00); #endif xvt_sign_stop(); if (_locale != NULL) { delete _locale; _locale = NULL; } } 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) // Puo' succedere! { while (a->Pending()) a->Dispatch(); a->ProcessIdle(); // Necessario per wxAUI a->Yield(true); // Non so se serva veramente } } /////////////////////////////////////////////////////////// // 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* WXUNUSED(name)) { return (fmt == CB_TEXT) && wxTheClipboard->IsSupported(wxDF_TEXT); } BOOLEAN xvt_cb_open(BOOLEAN WXUNUSED(writing)) { return wxTheClipboard->Open(); } BOOLEAN xvt_cb_put_data(CB_FORMAT cbfmt, char* WXUNUSED(name), long WXUNUSED(size), PICTURE WXUNUSED(pic)) { BOOLEAN ok = cbfmt == CB_TEXT && ptrClipboardData != NULL; if (ok) wxTheClipboard->SetData(new wxTextDataObject(ptrClipboardData)); return ok; } /////////////////////////////////////////////////////////// // 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 __WXMSW__ return OsWin32_HL_Crypt(data); #else return OsLinux_HL_Crypt(data); #endif } BOOLEAN xvt_dongle_hl_login(unsigned short address, const unsigned char* label, const unsigned char* password) { #ifdef __WXMSW__ return OsWin32_HL_Login(address, label, password); #else return OsLinux_HL_Login(address, label, password); #endif } BOOLEAN xvt_dongle_hl_logout() { #ifdef __WXMSW__ return OsWin32_HL_Logout(); #else return OsLinux_HL_Logout(); #endif } BOOLEAN xvt_dongle_hl_read(unsigned short reg, unsigned short* data) { #ifdef __WXMSW__ return OsWin32_HL_Read(reg, data); #else return OsLinux_HL_Read(reg, data); #endif } BOOLEAN xvt_dongle_hl_read_block(unsigned char* data) { #ifdef __WXMSW__ return OsWin32_HL_ReadBlock(data); #else return OsLinux_HL_ReadBlock(data); #endif } BOOLEAN xvt_dongle_hl_write(unsigned short reg, unsigned short data) { #ifdef __WXMSW__ return OsWin32_HL_Write(reg, data); #else return OsLinux_HL_Write(reg, data); #endif } BOOLEAN xvt_dongle_sl_crypt(unsigned short* data) { #ifdef __WXMSW__ return OsWin32_SL_Crypt(data); #else return OsLinux_SL_Crypt(data); #endif } BOOLEAN xvt_dongle_sl_login(const unsigned char* label, const unsigned char* password) { #ifdef __WXMSW__ return OsWin32_SL_Login(label, password); #else return OsLinux_SL_Login(label, password); #endif } BOOLEAN xvt_dongle_sl_logout() { #ifdef __WXMSW__ return OsWin32_SL_Logout(); #else return OsLinux_SL_Logout(); #endif } BOOLEAN xvt_dongle_sl_read_block(unsigned short reg, unsigned short size, unsigned short* data) { #ifdef __WXMSW__ return OsWin32_SL_ReadBlock(reg, size, data); #else return OsLinux_SL_ReadBlock(reg, size, data); #endif } BOOLEAN xvt_dongle_sl_write_block(unsigned short reg, unsigned short size, const unsigned short* data) { #ifdef __WXMSW__ return OsWin32_SL_WriteBlock(reg, size, data); #else return OsLinux_SL_WriteBlock(reg, size, data); #endif } /////////////////////////////////////////////////////////// // Font cache /////////////////////////////////////////////////////////// //WX_DECLARE_HASH_MAP(wxString, wxFont*, wxStringHash, wxStringEqual, wxFontHashMap); WX_DECLARE_STRING_HASH_MAP(wxFont*, wxFontHashMap); class TFontCache { wxFontHashMap* m_map; public: wxFont& FindOrCreate(int pointSize, int family, int style, int weight, bool underline, const wxString& face); void Destroy(); TFontCache() : m_map(NULL) { } ~TFontCache() { Destroy(); } } XVT_FONT_CACHE; void TFontCache::Destroy() { if (m_map) { m_map->clear(); // delete m_map; // NON funziona ma non si capisce perche': PAZIENZA! m_map = NULL; } } wxFont& TFontCache::FindOrCreate(int pointSize, int family, int style, int weight, bool underline, const wxString& face) { if (m_map == NULL) m_map = new wxFontHashMap; wxString key; key.Printf("%s_%d_%d_%d_%d", face, pointSize, style, weight, underline); wxFont* pFont = (*m_map)[key]; if (pFont == NULL) { pFont = new wxFont(pointSize, family, style, weight, underline, face); pFont->SetPointSize(pointSize); // Colpo di classe indispensabile per i PDF :-) (*m_map)[key] = pFont; } return *pFont; } /////////////////////////////////////////////////////////// // Image handling /////////////////////////////////////////////////////////// class TXVT_IMAGE : public wxImage { DECLARE_DYNAMIC_CLASS(TXVT_IMAGE); int m_nDepth; bool m_bDirty; #ifdef __WXMSW__ HBITMAP m_bitmap; #else wxBitmap* m_bitmap; #endif protected: void Destroy(); public: const wxImage& Image() const { return *this; } wxImage& Image() { m_bDirty = true; return *this; } #ifdef __WXMSW__ HBITMAP Bitmap(wxDC& dc); #else const wxBitmap& Bitmap(wxDC& dc); #endif COLOR GetPixel(int x, int y) const; void SetPixel(int x, int y, COLOR color); TXVT_IMAGE() : m_bitmap(NULL), m_nDepth(0), m_bDirty(false) { } ~TXVT_IMAGE(); }; IMPLEMENT_DYNAMIC_CLASS(TXVT_IMAGE, wxImage); #define CAST_TIMAGE(xvtimg, img) TXVT_IMAGE* img = wxDynamicCast(xvtimg, TXVT_IMAGE); #define CAST_IMAGE(xvtimg, img) const wxImage* img = wxDynamicCast(xvtimg, wxImage); // Chissa' perche' non esiste la GetRGB COLOR TXVT_IMAGE::GetPixel(int x, int y) const { if (IsTransparent(x, y)) return XVT_MAKE_COLOR(GetMaskRed(), GetMaskGreen(), GetMaskBlue()); const long pos = XYToIndex(x, y) * 3; unsigned char* data = GetData() + pos; return XVT_MAKE_COLOR(data[0], data[1], data[2]); } void TXVT_IMAGE::SetPixel(int x, int y, COLOR color) { SetRGB(x, y, XVT_COLOR_GET_RED(color), XVT_COLOR_GET_GREEN(color), XVT_COLOR_GET_BLUE(color)); m_bDirty = true; } #ifdef __WXMSW__ HBITMAP TXVT_IMAGE::Bitmap(wxDC& dc) { if (m_bDirty || m_bitmap == NULL || dc.GetDepth() != m_nDepth) { Destroy(); m_nDepth = dc.GetDepth(); m_bitmap = OsWin32_CreateBitmap(*this, dc); m_bDirty = false; } 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_bitmap = new wxBitmap(*this, m_nDepth); m_bDirty = false; } return *m_bitmap; } #endif void TXVT_IMAGE::Destroy() { if (m_bitmap != NULL) #ifdef __WXMSW__ ::DeleteObject(m_bitmap); #else delete m_bitmap; #endif m_bitmap = NULL; } TXVT_IMAGE::~TXVT_IMAGE() { Destroy(); } /////////////////////////////////////////////////////////// // Font Handling /////////////////////////////////////////////////////////// IMPLEMENT_DYNAMIC_CLASS(TFontId, wxObject); 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; } const 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 __WXMSW__ 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 __WXMSW__ // 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 sfondi 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); } const wxFont& ff1 = XVT_FONT_CACHE.FindOrCreate(nSize, Family(), Style(), Weight(), Underline(), FaceName()); if (ff1.GetPointSize() > 0) return ff1; XVT_FONT_CACHE.Destroy(); const wxFont& ff2 = XVT_FONT_CACHE.FindOrCreate(nSize, Family(), Style(), Weight(), Underline(), FaceName()); return ff2; } 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) { if (win != NULL_WIN && win != PRINTER_WIN) { CAST_DC(win, dc); CAST_COLOR(col, colour); wxBrush* brush = wxTheBrushList->FindOrCreateBrush(colour, 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 (win != NULL_WIN && r != NULL) { CAST_DC(win, dc); const wxRect rect = RCT2Rect(r); const wxPoint c(rect.x+rect.width/2, rect.y+rect.height/2); if (abs(rect.width - rect.height) < 2) dc.DrawArc(sx, sy, ex, ey, c.x, c.y); else { const double pi = acos(-1.0); double sa = atan2(double(c.y-sy), double(sx-c.x)) * 180 / pi; if (sa < 0) sa += 360; double ea = atan2(double(c.y-ey), double(ex-c.x)) * 180 / pi; while (ea < sa) ea += 360; dc.DrawEllipticArc(rect.x, rect.y, rect.width, rect.height, sa, ea); } } } void xvt_dwin_draw_gradient_circular(WINDOW win, const RCT* r, COLOR col1, COLOR col2, const PNT* center) { if (win != NULL_WIN && r != NULL) { CAST_DC(win, dc); const wxRect rect = RCT2Rect(r); CAST_COLOR(col1, color1); CAST_COLOR(col2, color2); if (center != NULL) dc.GradientFillConcentric(rect, color1, color2, wxPoint(center->h, center->v)); else dc.GradientFillConcentric(rect, color1, color2); } } void xvt_dwin_draw_gradient_linear(WINDOW win, const RCT* r, COLOR col1, COLOR col2, int angle) { if (win != NULL_WIN && r != NULL) { CAST_DC(win, dc); const wxRect rect = RCT2Rect(r); CAST_COLOR(col1, color1); CAST_COLOR(col2, color2); angle %= 360; if (angle < 0) angle += 360; wxDirection dir = wxDOWN; switch (angle / 90) { case 0: dir = wxRIGHT; break; case 1: dir = wxUP; break; case 2: dir = wxLEFT; break; default: dir = wxDOWN; break; } dc.GradientFillLinear(rect, color1, color2, dir); } } void xvt_dwin_draw_icon(WINDOW win, int x, int y, int rid) { const wxIcon ico = xvtart_GetIconResource(rid); if (ico.IsOk()) { CAST_DC(win, dc); dc.DrawIcon(ico, x, y); } } void xvt_dwin_draw_icon_rect(WINDOW win, RCT* rct, int rid) { const int w = xvt_rect_get_width(rct); const int h = xvt_rect_get_height(rct); const int s = min(w/16*16, h/16*16); if (s > 0) { const wxIcon ico = xvtart_GetIconResource(rid, NULL, s); if (ico.IsOk()) { CAST_DC(win, dc); dc.DrawIcon(ico, rct->left+(w-s)/2, rct->top+(h-s)/2); } } } 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 __WXMSW__ 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 img, const RCT* dest, const RCT* source) { CAST_TIMAGE(img, image); if (image != NULL) { CAST_DC(win, dc); const wxRect src = RCT2Rect(source); const wxRect dst = RCT2Rect(dest); DrawImageOnDC(dc, image, dst, src); } } void xvt_dwin_draw_oval(WINDOW win, const RCT* rctp) { CAST_DC(win, dc); const wxRect rct = RCT2Rect(rctp); dc.DrawEllipse(rct); } void xvt_dwin_draw_pie(WINDOW win, const RCT *rctp, int WXUNUSED(start_x), int WXUNUSED(start_y), int WXUNUSED(stop_x), int WXUNUSED(stop_y)) { SORRY_BOX(); xvt_dwin_draw_oval(win, rctp); } 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 (win != NULL_WIN && lpnts != NULL && npnts > 1) // Occorrono almeno 2 punti { 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 = RCT2Rect(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 = RCT2Rect(rctp); dc.DrawRoundedRectangle(rct, min(oval_width, oval_height)); } void xvt_dwin_draw_dotted_rect(WINDOW win, RCT *rctp) { #ifdef __WXMSW__ 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 = RCT2Rect(&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) { // Attenzione: non funziona la chiamate in cascata a xvt_font_get_metrics CAST_DC(win, dc); const wxString str = "Mg"; 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; if (s && *s && len != 0) { CAST_DC(win, dc); wxString str = s; if (str.StartsWith("ABCDEFGH") || str.StartsWith("MMMMMMMM")) { const wxString emme('G', str.Length()); // Questa lettera cambia con le mode str = emme; } if (len > 0) str.Truncate(len); int height = 0; dc.GetTextExtent(str, &width, &height); } return width; } void xvt_dwin_invalidate_rect(WINDOW win, const RCT* rctp) { if (win != NULL_WIN) { CAST_WIN(win, w); if (rctp != NULL) { const wxRect rct = RCT2Rect(rctp); w.Refresh(false, &rct); } else w.Refresh(false); } } BOOLEAN xvt_dwin_is_update_needed(WINDOW win, const RCT* rctp) { if (win != NULL_WIN && rctp != NULL) { if (win == PRINTER_WIN || win == SCREEN_WIN) return TRUE; CAST_WIN(win, w); // child windows and TASK_WIN const wxRect rect1 = RCT2Rect(rctp); const wxRect rect2 = w.GetUpdateClientRect(); return rect1.Intersects(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) { const wxRect rct = RCT2Rect(rctp); if (!rct.IsEmpty()) // w.ScrollWindow(dh, dv, &rct); // Metodo ortodosso ma impreciso di un pixel w.Refresh(false, &rct); // Pezza "TEMPORANEA" per evitare artefatti } 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); dc.SetDirty(); } 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) { CAST_TDC(win, dc); CAST_FONT(font_id, font); 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); if (tdc._pnt != to) { wxDC& dc = tdc.GetDC(); dc.DrawLine(tdc._pnt, to); // dc.DrawPoint(to); // Non scommentare o cancellare: Un giorno capiro' il perche' servisse } 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); CAST_FONT(dest_font_id, dst); CAST_FONT(src_font_id, src); 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 CAST_FONT(font_id, font) const 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) { TFontId* fp = wxDynamicCast(font_id, TFontId); if (fp != NULL) delete fp; } BOOLEAN xvt_font_get_family(XVT_FNTID font_id, char* buf, long max_buf) { BOOLEAN ok = font_id != NULL && buf != NULL && max_buf > 0; if (ok) { CAST_FONT(font_id, font); wxStrncpy(buf, font.FaceName(), max_buf); buf[max_buf-1] = '\0'; } return ok; } 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) { CAST_FONT(font_id, font); WINDOW win = font.Win(); if (win != PRINTER_WIN) win = TASK_WIN; // Non mi fido troppo della finestra su cui il font e' mappato CAST_DC(win, dc); const wxString str = "Mq"; int height = 0, desc = 0, lead = 0; const wxFont& ff = font.Font(&dc, win); dc.GetTextExtent(str, NULL, &height, &desc, &lead, (wxFont*)&ff); if (height <= 0 || height > 64000) // Gestisce eventuali anomalie alla meno peggio { wxASSERT(false); height = ff.GetPointSize(); desc = height / 5; lead = 0; } 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) { const long len = xvt_font_serialize(font_id, buf, max_buf); return len > 0 && len < max_buf; } long xvt_font_get_size(XVT_FNTID font_id) { CAST_FONT(font_id, font); return font.PointSize(); } XVT_FONT_STYLE_MASK xvt_font_get_style(XVT_FNTID font_id) { CAST_FONT(font_id, font); return font.Mask(); } WINDOW xvt_font_get_win(XVT_FNTID font_id) { CAST_FONT(font_id, font); return font.Win(); } BOOLEAN xvt_font_is_mapped(XVT_FNTID font_id) { return xvt_font_get_win(font_id) != NULL_WIN; } void xvt_font_map(XVT_FNTID font_id, WINDOW win) { CAST_FONT(font_id, font); font.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) { CAST_FONT(font_id, font); font.SetFaceName(family); } void xvt_font_set_size(XVT_FNTID font_id, long size) { CAST_FONT(font_id, font); font.SetPointSize(size); } void xvt_font_set_style(XVT_FNTID font_id, XVT_FONT_STYLE_MASK mask) { CAST_FONT(font_id, font); 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 CAST_FONT(font_id, font); const char* name = font.FaceName(); const int size = font.PointSize(); const int italic = (font.Mask() & XVT_FS_ITALIC) != 0; const int weight = (font.Mask() & XVT_FS_BOLD) ? 700 : 400; wxString str; str.Printf("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); if (buf != NULL && max_buf > 0) { wxStrncpy(buf, str, max_buf); buf[max_buf-1] = '\0'; } return str.Len(); } void xvt_font_unmap(XVT_FNTID font_id) { CAST_FONT(font_id, font); 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 __WXMSW__ _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) { if (mbs[0] == mbs[1] && wxIsPathSeparator(mbs[0])) { volume.insert(size_t(0), size_t(2), wxFILE_SEP_PATH); // Mette due slash all'inizio if (!wxIsPathSeparator(path[0])) volume << wxFILE_SEP_PATH; // Accoda uno slash path.insert(0, volume); *volname = '\0'; } else { wxStrcpy(volname, volume); #ifdef __WXMSW__ if (volname[0] != '\0' && volname[1] == '\0') wxStrcat(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) { BOOLEAN ok = dirp != NULL && path != NULL && sz_path > 0; if (ok) { wxStrncpy(path, dirp->path, sz_path-1); path[sz_path-1] = '\0'; } return ok; } BOOLEAN xvt_fsys_convert_str_to_dir(const char *path, DIRECTORY *dirp) { BOOLEAN ok = path != NULL && dirp != NULL; if (ok) { const int sz = sizeof(dirp->path)-1; wxStrncpy(dirp->path, path, sz); dirp->path[sz] = '\0'; } return ok; } BOOLEAN xvt_fsys_convert_fspec_to_str(const FILE_SPEC *fs, char *path, int sz_path) { BOOLEAN ok = FALSE; if (fs != NULL && path != NULL && sz_path > 0) { char mbs[_MAX_PATH]; xvt_fsys_build_pathname(mbs, "", fs->dir.path, fs->name, fs->type, NULL); wxStrncpy(path, mbs, sz_path); ok = *path > ' '; } return ok; } BOOLEAN xvt_fsys_convert_str_to_fspec(const char *mbs, FILE_SPEC *fs) { BOOLEAN ok = FALSE; if (fs != NULL) { memset(fs, 0, sizeof(FILE_SPEC)); wxStrcpy(fs->creator, "CAMPO"); if (mbs && *mbs) { char volume[_MAX_DRIVE], path[_MAX_PATH]; xvt_fsys_parse_pathname(mbs, volume, path, fs->name, fs->type, NULL); wxStrcpy(fs->dir.path, volume); wxStrcat(fs->dir.path, path); ok = fs->name[0] != '\0'; } } return ok; } void xvt_fsys_get_default_dir(DIRECTORY *dirp) { if (_startup_dir.IsEmpty()) _startup_dir = ::wxGetCwd(); xvt_fsys_convert_str_to_dir(_startup_dir, dirp); } BOOLEAN xvt_fsys_get_dir(DIRECTORY *dirp) { return xvt_fsys_convert_str_to_dir(::wxGetCwd(), dirp); } static wxString get_disk_root(const char* path) { wxString str; if (path && *path) { str = path; if (!wxEndsWithPathSeparator(str)) str << wxFILE_SEP_PATH; wxChar drive[_MAX_DRIVE], dir[_MAX_DIR]; xvt_fsys_parse_pathname(str,drive,dir,NULL,NULL,NULL); if (*drive) str = drive; else str = dir; if (!wxEndsWithPathSeparator(str)) str << wxFILE_SEP_PATH; } return str; } // Il disco e' un floppy? BOOLEAN xvt_fsys_is_floppy_drive(const char* path) { BOOLEAN yes = xvt_fsys_is_removable_drive(path); if (yes) { const unsigned long mb = xvt_fsys_get_disk_size(path, 'M'); // Dimensioni in Mb yes = mb < 4; // E' un vero floppy solo se e' piu' piccolo di 4 Mb } return yes; } // Il disco e' rimuovibile? (floppy / memory stick) BOOLEAN xvt_fsys_is_removable_drive(const char* path) { BOOLEAN yes = FALSE; if (path && *path) { #ifdef __WXMSW__ const wxString strRoot = get_disk_root(path); yes = ::GetDriveType(strRoot) == DRIVE_REMOVABLE; #else char dev[_MAX_PATH]; OsLinux_GetFileSys(path, dev, NULL, NULL); yes = strncmp(dev, "/dev/fd", 7) == 0; #endif } return yes; } BOOLEAN xvt_fsys_is_network_drive(const char* path) { BOOLEAN yes = FALSE; if (path && *path) { if (wxIsPathSeparator(path[0]) && wxIsPathSeparator(path[1])) yes = TRUE; else { #ifdef __WXMSW__ const wxString strRoot = get_disk_root(path); yes = ::GetDriveType(strRoot) == DRIVE_REMOTE; #else yes = OsLinux_IsNetworkDrive(path); #endif } } return yes; } BOOLEAN xvt_fsys_is_fixed_drive(const char* path) { BOOLEAN yes = FALSE; if (path && *path) { if (!wxIsPathSeparator(path[0]) || !wxIsPathSeparator(path[1])) { #ifdef __WXMSW__ const wxString strRoot = get_disk_root(path); yes = ::GetDriveType(strRoot) == DRIVE_FIXED; #else yes = !(xvt_fsys_is_network_drive(path) || xvt_fsys_is_removable_drive(path)); #endif } } return yes; } static unsigned long compute_disk_size(const char* path, bool tot, char unit) { long nVal = 0; if (path && *path) { const wxString strRoot = get_disk_root(path); wxLongLong total = 0, unused = 0; wxGetDiskSpace(strRoot, &total, &unused); __int64 nBytes = tot ? total.ToDouble() : unused.ToDouble(); if (nBytes > 0) { 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); 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'); } // Usr friendly implementation long xvt_fsys_file_attr(const char* path, long attr) { long ret = 0; if (path && *path && attr >= XVT_FILE_ATTR_MINIMUM && attr <= XVT_FILE_ATTR_MAXIMUM) { const wxString name(path); switch (attr) { case XVT_FILE_ATTR_EXIST: ret = ::wxFileExists(name); break; case XVT_FILE_ATTR_READ: ret = ::wxAccess(name, 0x1) != 0; break; case XVT_FILE_ATTR_WRITE: ret = ::wxAccess(name, 0x2) != 0; break; case XVT_FILE_ATTR_DIRECTORY: ret = ::wxDirExists(name); break; case XVT_FILE_ATTR_SIZE: { const wxULongLong sz = wxFileName::GetSize(name); ret = sz.GetHi() != 0 ? INT_MAX : sz.GetLo(); } break; case XVT_FILE_ATTR_MTIME: ret = ::wxFileModificationTime(name); break; default: break; } } return ret; } // Original XVT implementation long xvt_fsys_get_file_attr(const FILE_SPEC* fs, long attr) { char mbs[_MAX_PATH]; xvt_fsys_convert_fspec_to_str(fs, mbs, sizeof(mbs)); return xvt_fsys_file_attr(mbs, attr); } /////////////////////////////////////////////////////////// // File system /////////////////////////////////////////////////////////// SLIST xvt_fsys_list_files(const char *type, const 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 __WXMSW__ 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() { wxASSERT(!_strSavedir.IsEmpty()); ::wxSetWorkingDirectory(_strSavedir); _strSavedir = wxEmptyString; } void xvt_fsys_save_dir() { wxASSERT(_strSavedir.IsEmpty()); _strSavedir = ::wxGetCwd(); } BOOLEAN xvt_fsys_set_dir(const DIRECTORY *dirp) { return ::wxSetWorkingDirectory(dirp->path); } /////////////////////////////////////////////////////////// // Images /////////////////////////////////////////////////////////// inline bool XVT_SAME_COLOR(COLOR col1, COLOR col2) { return (col1 & 0x00FFFFFF) == (col2 & 0x00FFFFFF); } 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 = RCT2Rect(&rct); } else r = RCT2Rect(src); wxBitmap bmp(r.GetWidth(), r.GetHeight()); CAST_DC(win, wdc); wxMemoryDC mdc(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 WXUNUSED(format), short width, short height, COLOR color) { TXVT_IMAGE* i = new TXVT_IMAGE; i->Image().Create(width, height); if (color != COLOR_INVALID) { CAST_COLOR(color, rgb); #if wxCHECK_VERSION(2,9,0) if (rgb.Red() == rgb.Green() && rgb.Green() == rgb.Blue()) i->Image().Clear(rgb.Red()); else #endif { const wxRect rct(0, 0, width, height); i->Image().SetRGB(rct, rgb.Red(), rgb.Green(), rgb.Blue()); } } return (XVT_IMAGE)i; } void xvt_image_destroy(XVT_IMAGE img) { CAST_TIMAGE(img, image); if (image != NULL) delete image; } int xvt_image_find_clut_index(XVT_IMAGE img, COLOR rgb) { CAST_IMAGE(img, image); int i = -1; if (image && image->Ok() && image->HasPalette()) { const wxPalette& pal = image->GetPalette(); for (i = 255; i >= 0; i--) { unsigned char ri, gi, bi; if (pal.GetRGB(i, &ri, &gi, &bi)) { const COLOR rgbi = XVT_MAKE_COLOR(ri, gi, bi); if ((rgbi & 0x00FFFFFF) == (rgb & 0x00FFFFFF)) break; } } } return i; } COLOR xvt_image_get_clut(XVT_IMAGE img, short index) { CAST_IMAGE(img, image); if (image && image->Ok() && image->HasPalette()) { const wxPalette& pal = image->GetPalette(); unsigned char r, g, b; if (pal.GetRGB(index, &r, &g, &b)) return XVT_MAKE_COLOR(r, g, b); } return COLOR_INVALID; } void xvt_image_get_dimensions(XVT_IMAGE image, short* width, short* height) { *width = *height = 0; CAST_IMAGE(image, img); if (img != NULL && img->Ok()) { *width = img->GetWidth(); *height = img->GetHeight(); } } XVT_IMAGE_FORMAT xvt_image_get_format(XVT_IMAGE image) { CAST_IMAGE(image, img); if (img != NULL && img->Ok()) return img->HasPalette() ? XVT_IMAGE_CL8 : XVT_IMAGE_RGB; return XVT_IMAGE_NONE; } short xvt_image_get_ncolors(XVT_IMAGE image) { int n = 0; if (xvt_image_get_format(image) == XVT_IMAGE_CL8) { CAST_IMAGE(image, i); const wxPalette& pal = i->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) { CAST_TIMAGE(image, i); if (i != NULL && i->Ok()) return i->GetPixel(x, y); return COLOR_INVALID; } XVT_IMAGE xvt_image_read(const char* filenamep) { TXVT_IMAGE* i = NULL; #ifdef __WXMSW__ 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->LoadFile(name); if (!i->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) { CAST_TIMAGE(image, i); if (i != NULL && i->Ok() && i->HasPalette()) { CAST_COLOR(color, c); wxImage& bmp = i->Image(); // Set dirty! const COLOR old_trans = XVT_MAKE_COLOR(bmp.GetMaskRed(), bmp.GetMaskGreen(), bmp.GetMaskBlue()); const int idx = xvt_image_find_clut_index(image, old_trans); if (idx == index) bmp.SetMaskColour(c.Red(), c.Green(), c.Blue()); const wxPalette& pal = bmp.GetPalette(); unsigned char ri, gi, bi; pal.GetRGB(index, &ri, &gi, &bi); const COLOR old_color = XVT_MAKE_COLOR(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++) { const COLOR rgb = i->GetPixel(x, y); if (XVT_SAME_COLOR(rgb, old_color)) i->SetPixel(x, y, color); } } } void xvt_image_replace_color(XVT_IMAGE image, COLOR old_color, COLOR new_color) { CAST_TIMAGE(image, i); if (i != NULL && i->Ok()) { if (i->HasPalette()) { int index = -1; while (true) { const int idx = xvt_image_find_clut_index(image, old_color); if (idx > index) { xvt_image_set_clut(image, idx, new_color); index = idx; } else break; } } else { wxImage& bmp = i->Image(); // Set dirty! const COLOR old_trans = XVT_MAKE_COLOR(bmp.GetMaskRed(), bmp.GetMaskGreen(), bmp.GetMaskBlue()); const int w = bmp.GetWidth(); const int h = bmp.GetHeight(); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { const COLOR rgb = i->GetPixel(x, y); if (XVT_SAME_COLOR(rgb, old_color)) i->SetPixel(x, y, new_color); } // Imposto la nuova trasparenza se cambiata if (XVT_SAME_COLOR(old_trans, old_color)) bmp.SetMaskColour(XVT_COLOR_GET_RED(new_color), XVT_COLOR_GET_GREEN(new_color), XVT_COLOR_GET_BLUE(new_color)); } } } void xvt_image_set_ncolors(XVT_IMAGE WXUNUSED(image), short WXUNUSED(ncolors)) { // SORRY_BOX(); } void xvt_image_set_pixel(XVT_IMAGE image, short x, short y, COLOR color) { CAST_TIMAGE(image, i); if (i != NULL && i->Ok()) i->SetPixel(x, y, color); } void xvt_image_transfer(XVT_IMAGE dstimage, XVT_IMAGE srcimage, RCT *dstrctp, RCT *srcrctp) { CAST_TIMAGE(dstimage, dst); CAST_TIMAGE(srcimage, src); if (dst != NULL && src != NULL) { const wxRect rctDst = RCT2Rect(dstrctp); const wxRect rctSrc = RCT2Rect(srcrctp); wxMemoryDC dc; wxBitmap bmp(*dst); dc.SelectObject(bmp); DrawImageOnDC(dc, src, rctDst, rctSrc); dst->Image() = bmp.ConvertToImage(); dc.SelectObject(wxNullBitmap); } } BOOLEAN xvt_image_filter(XVT_IMAGE image, IMAGE_FILTER filter, void* param) { CAST_TIMAGE(image, img); BOOLEAN ok = img != NULL && img->Ok(); if (ok) { const short w = img->GetWidth(); const short h = img->GetHeight(); ok = w > 0 && h > 0; if (ok) { const int nPixelSize = img->HasAlpha() ? 4 : 3; for (short y = 0; y < h; y++) { unsigned char* rgb = img->Image().GetData() + nPixelSize*y; for (short x = 0; x < w; x++, rgb += nPixelSize) filter(x, y, rgb, param); } } } return ok; } /////////////////////////////////////////////////////////// // 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 /////////////////////////////////////////////////////////// static int xvt_menu_count(const MENU_ITEM* m) { int n = 0; if (m != NULL) 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 = wxStaticCast((wxObject*)win, TTaskWin); 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(const MENU_ITEM *menu_p, WINDOW win, PNT pos, XVT_POPUP_ALIGNMENT /* alignment */, MENU_TAG /* item */) { wxMenu menu; for (const MENU_ITEM* mi = menu_p; mi != NULL && mi->tag != 0; mi++) { if (mi->separator || mi->text == NULL) menu.AppendSeparator(); else { wxMenuItem* item = NULL; if (mi->checkable) { item = menu.AppendCheckItem(mi->tag, mi->text); item->Check(mi->checked); } else item = menu.Append(mi->tag, mi->text); // Operazioni fattibili solo dopo la menu.Append(), non prima! item->Enable(mi->enabled); } } wxPoint mp = wxDefaultPosition; if (pos.h >= 0 && pos.v >= 0) { mp.x = pos.h; mp.y = pos.v; } CAST_WIN(win, w); return w.PopupMenu(&menu, mp); } 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) { wxMenuBar* pMenuBar = _task_win->GetMenuBar(); if (pMenuBar != NULL) { for (int m = pMenuBar->GetMenuCount()-1; m >= 0; m--) { const wxString 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 WXUNUSED(font_id)) { XVT_ASSERT(win == TASK_WIN); } static wxMenuItem* GetXvtMenuItem(WINDOW win, MENU_TAG tag) { wxMenuItem* item = NULL; wxFrame* pFrame = wxDynamicCast((wxObject*)win, wxFrame); if (pFrame != NULL) { wxMenuBar* bar = pFrame->GetMenuBar(); if (bar != NULL) item = bar->FindItem(tag); } 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, const 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 = wxStaticCast((wxObject*)win, TTaskWin); //occhio w->SetMenuTree(tree); } else { CAST_TWIN(win, w); w.SetMenuTree(tree); } } void xvt_menu_update(WINDOW /*win*/) { wxMenuBar* bar = _task_win != NULL ? _task_win->GetMenuBar() : NULL; if (bar) bar->Refresh(); } /////////////////////////////////////////////////////////// // Palette management /////////////////////////////////////////////////////////// short xvt_palet_add_colors(XVT_PALETTE WXUNUSED(palet), COLOR* WXUNUSED(colorsp), short numcolors) { return numcolors; } short xvt_palet_add_colors_from_image(XVT_PALETTE WXUNUSED(palet), XVT_IMAGE image) { return xvt_image_get_ncolors(image); } XVT_PALETTE xvt_palet_create(XVT_PALETTE_TYPE WXUNUSED(type), XVT_PALETTE_ATTR WXUNUSED(reserved)) { return NULL; } void xvt_palet_destroy(XVT_PALETTE WXUNUSED(palet)) { SORRY_BOX(); } short xvt_palet_get_colors(XVT_PALETTE WXUNUSED(palet), COLOR* WXUNUSED(colorsp), short WXUNUSED(maxcolors)) { return 0; } short xvt_palet_get_ncolors(XVT_PALETTE WXUNUSED(palet)) { return 0; } int xvt_palet_get_tolerance(XVT_PALETTE WXUNUSED(p)) { return 0; } void xvt_palet_set_tolerance(XVT_PALETTE WXUNUSED(p), int WXUNUSED(t)) { SORRY_BOX(); } /////////////////////////////////////////////////////////// // Rectangles /////////////////////////////////////////////////////////// int xvt_rect_get_height(const RCT *rctp) { return rctp ? abs(rctp->bottom - rctp->top) : 0; // 3.1 return rctp ? rctp->bottom - rctp->top : 0; } int xvt_rect_get_width(const RCT *rctp) { return rctp ? abs(rctp->right - rctp->left) : 0; // 3.1 return rctp ? rctp->right - rctp->left : 0; } BOOLEAN xvt_rect_has_point(const RCT *rctp, PNT pnt) { const wxRect rct = RCT2Rect(rctp); return rct.Contains(pnt.h, pnt.v); } BOOLEAN xvt_rect_intersect(RCT *drctp, const RCT *rctp1, const RCT *rctp2) { const wxRect rect1 = RCT2Rect(rctp1); const wxRect rect2 = RCT2Rect(rctp2); const BOOLEAN yes = rect1.Intersects(rect2); if (drctp) { if (yes) { /* 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; */ const wxRect rect0 = rect1.Intersect(rect2); Rect2RCT(rect0, drctp); } else { // drctp->left = drctp->right = rect1.x; // drctp->top = drctp->bottom = rect1.y; xvt_rect_set_null(drctp); } } 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; } void xvt_rect_set_null(RCT* rctp) { XVT_ASSERT(rctp != NULL); memset(rctp, 0, sizeof(RCT)); } 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; xvt_rect_set(rctp, pos.h, pos.v, pos.h + w, pos.v + h); } return ok; } void xvt_rect_deflate(RCT *rctp, short ix, short iy) { if (rctp != NULL) { rctp->left += ix; rctp->right -= ix; rctp->top += iy; rctp->bottom -= iy; } } void xvt_rect_inflate(RCT *rctp, short ix, short iy) { if (rctp != NULL) { rctp->left -= ix; rctp->right += ix; rctp->top -= iy; rctp->bottom += iy; } } /////////////////////////////////////////////////////////// // 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_FNTID xvt_res_get_font(int rid) { XVT_FNTID f = xvt_font_create(); if (rid <= 0) { CAST_FONT(f, font); font.Copy(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); } return f; } XVT_IMAGE xvt_res_get_icon(int rid) { const wxIcon icon = xvtart_GetIconResource(rid); int w = icon.GetWidth(); if (w <= 0) w = 32; int h = icon.GetHeight(); if (h <= 0) h = 32; wxBitmap bmp(w, h, icon.GetDepth()); { wxMemoryDC dc(bmp); dc.DrawIcon(icon, 0, 0); } XVT_IMAGE_FORMAT xif = bmp.GetDepth()>8 ? XVT_IMAGE_RGB : XVT_IMAGE_CL8; XVT_IMAGE img = xvt_image_create(xif, w, h, 0); ((TXVT_IMAGE*)img)->Image() = bmp.ConvertToImage(); return img; } XVT_IMAGE xvt_res_get_image(int rid) { const wxString strFileName = xvtart_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 = (char*)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("", "", xvtart_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.Printf("/Menu_%s-%X", (const char*)strName.Left(3), (rid-1)%16); } else strName.Printf("/Menu_%d", rid); ini.SetPath(strName); wxString strItem; for (int i = 0; i < MAX_MENU; i++) { MENU_ITEM* mi = &TheMenu[i]; strItem.Printf("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.Printf("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 = xvtart_GetResourceName("String", rid); wxStrncpy(s, str, sz_s); s[sz_s-1] = '\0'; return s; } /////////////////////////////////////////////////////////// // Scroll bars /////////////////////////////////////////////////////////// #define CAST_GAUGE(win, pb) wxGauge& pb = *wxStaticCast((wxObject*)win, wxGauge); #define CAST_SLIDER(win, sc) wxSlider& sc = *wxStaticCast((wxObject*)win, wxSlider); #define CAST_SCROLL(win, sb) wxScrollBar& sb = *wxStaticCast((wxObject*)win, wxScrollBar); #define CAST_SCROLL_TYPE(t, dir) const int dir = t == HSCROLL ? wxHORIZONTAL : wxVERTICAL; int xvt_sbar_get_pos(WINDOW win, SCROLL_TYPE t) { int pos = 0; switch (t) { case HSCROLL: case VSCROLL: { CAST_WIN(win, w); CAST_SCROLL_TYPE(t, dir); pos = w.GetScrollPos(dir); } break; case HVGAUGE: { CAST_GAUGE(win, g); pos = g.GetValue(); } break; case HVSLIDER: { CAST_SLIDER(win, g); pos = g.GetValue(); } break; default: { CAST_SCROLL(win, sb); pos = sb.GetThumbPosition(); } break; } return pos; } int xvt_sbar_get_proportion(WINDOW win, SCROLL_TYPE t) { int p = 1; switch (t) { case HSCROLL: case VSCROLL: { CAST_WIN(win, w); CAST_SCROLL_TYPE(t, dir); p = w.GetScrollThumb(dir); } break; case HVSLIDER: { CAST_SLIDER(win, sc); p = sc.GetPageSize(); } break; default: { CAST_SCROLL(win, sb); p = sb.GetThumbSize(); } break; } return p; } void xvt_sbar_get_range(WINDOW win, SCROLL_TYPE t, int *minp, int *maxp) { wxASSERT(minp && maxp); *minp = 0; switch (t) { case HSCROLL: case VSCROLL: { CAST_WIN(win, w); CAST_SCROLL_TYPE(t, dir); *maxp = w.GetScrollRange(dir); } break; case HVGAUGE: { CAST_GAUGE(win, g); *maxp = g.GetRange(); } break; default: { CAST_SCROLL(win, sb); *maxp = sb.GetRange(); } break; } } void xvt_sbar_set_pos(WINDOW win, SCROLL_TYPE t, int pos) { switch(t) { case HSCROLL: case VSCROLL: { CAST_WIN(win, w); CAST_SCROLL_TYPE(t, dir); w.SetScrollPos(dir, pos); } break; case HVGAUGE: { CAST_GAUGE(win, g); if (g.GetRange() <= 1) g.Pulse(); else g.SetValue(pos); } break; case HVSLIDER: { CAST_SLIDER(win, g); g.SetValue(pos); } break; default: { CAST_SCROLL(win, sb); const int range = sb.GetRange(); const int size = sb.GetThumbSize(); sb.SetScrollbar(pos, size, range, size); } break; } } void xvt_sbar_set_proportion(WINDOW win, SCROLL_TYPE t, int proportion) { switch (t) { case HSCROLL: case 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); } break; case HVSLIDER: { CAST_SLIDER(win, sc); sc.SetPageSize(proportion); sc.SetTickFreq(sc.GetMax()/proportion, 0); } break; default: { CAST_SCROLL(win, sb); const int pos = sb.GetThumbPosition(); const int range = sb.GetRange(); sb.SetScrollbar(pos, proportion, range, proportion); } break; } } void xvt_sbar_set_range(WINDOW win, SCROLL_TYPE t, int min, int max) { XVT_ASSERT(min == 0 && max >= min); switch (t) { case HSCROLL: case 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); } break; case HVGAUGE: { CAST_GAUGE(win, g); g.SetRange(max); } break; case HVSLIDER: { CAST_SLIDER(win, g); g.SetRange(min, max); } break; default: { CAST_SCROLL(win, sb); const int pos = sb.GetThumbPosition(); const int size = sb.GetThumbSize(); sb.SetScrollbar(pos, size, max, size); } break; } } /////////////////////////////////////////////////////////// // Window manager /////////////////////////////////////////////////////////// void xvt_scr_beep(void) { xvt_sys_beep(0); } WINDOW xvt_scr_get_focus_topwin(void) { wxWindow* w = _task_win->FindFocus(); while (w != NULL && w->IsKindOf(CLASSINFO(wxControl))) w = w->GetParent(); return (WINDOW)w; } WINDOW xvt_scr_get_focus_vobj(void) { return (WINDOW)_task_win->FindFocus(); } SLIST xvt_scr_list_wins() { SLIST list = xvt_slist_create(); _nice_windows.BeginFind(); for (wxHashTable::Node* node = _nice_windows.Next(); node; node = _nice_windows.Next()) { wxWindow* pWin = wxDynamicCast(node->GetData(), wxWindow); if (pWin != NULL) { const char* title = pWin->GetLabel(); xvt_slist_add_at_elt(list, NULL, title, (long)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) { return list != NULL ? 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) { if (list != NULL) { 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) { if (list != NULL && 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) { return list != NULL ? list->head : NULL; } SLIST_ELT xvt_slist_get_next(SLIST list, SLIST_ELT item) { return (SLIST_ELT)(list != NULL && item != NULL ? 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 ? wxStrdup(str) : NULL; // bleah! } char* xvt_str_number_format(char* str, int size) { #ifdef __WXMSW__ OsWin32_NumberFormat(str, size); #else wxString txt; for (const char* s = str; *s; s++) { if (isdigit(*s)) txt << *s; else { if (*s == '.') txt << ','; } } wxStrncpy(str, txt, size); #endif return str; } static const char* const ENCRYPTION_KEY = "QSECOFR-"; int xvt_str_encode(const char* text, char* cipher, int mode) { int i = 0; switch (mode) { case 1: // BASE64 break; default: // AGA for (i = 0; text[i]; i++) cipher[i] = text[i] + (i < 8 ? ENCRYPTION_KEY[i] : text[i - 8]); cipher[i] = '\0'; break; } return i; } int xvt_str_decode(const char* cipher, char* text, int mode) { int i = 0; switch (mode) { case 1: // BASE64 break; default: // AGA for (i = 0; cipher[i]; i++) text[i] = cipher[i] - (i < 8 ? ENCRYPTION_KEY[i] : text[i - 8]); text[i] = '\0'; break; } return i; } 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) { wxString s(str); s.MakeUpper(); wxStrcpy(str, s); } void xvt_str_make_lower(char* str) { wxString s(str); s.MakeLower(); wxStrcpy(str, s); } double xvt_str_fuzzy_compare (const char* s1, const char* s2) { return fstrcmp(s1, s2); } double xvt_str_fuzzy_compare_ignoring_case (const char* s1, const char* s2) { wxString str1(s1); str1.MakeUpper(); wxString str2(s2); str2.MakeUpper(); return fstrcmp(str1, str2); } BOOLEAN xvt_chr_is_digit(int c) { return (c <= 255) && wxIsdigit(c); } BOOLEAN xvt_chr_is_alpha(int c) { return (c <= 255) && wxIsalpha(c); } BOOLEAN xvt_chr_is_alnum(int c) { return (c <= 255) && wxIsalnum(c); } int xvt_net_get_status() { int nStatus = 0; //stoppa il log di wxWidgets per non avere segnalazioni di errori incomprensibili! const bool bLogEnabled = wxLog::EnableLogging(false); wxDialUpManager* dum = wxDialUpManager::Create(); if (dum != NULL) { if (dum->IsOk() && dum->IsOnline()) { nStatus = 0x1; // 1 = Online if (dum->IsAlwaysOnline()) { nStatus |= 0x2; // 2 = Always Online wxIPV4address addr; if (addr.Hostname("www.google.com")) nStatus |= 0x4; // 4 = Connected to web } } delete dum; } wxLog::EnableLogging(bLogEnabled); return nStatus; } /////////////////////////////////////////////////////////// // XVT system calls (added by Guy) /////////////////////////////////////////////////////////// void xvt_sys_beep(int severity) { #ifdef __WXMSW__ OsWin32_Beep(severity); #else wxBell(); #endif } BOOLEAN xvt_sys_get_host_name(char* name, int maxlen) { wxString str = wxGetHostName(); wxStrncpy(name, str, maxlen); name[maxlen-1] = '\0'; return *name > '\0'; } BOOLEAN xvt_sys_get_user_name(char* name, int maxlen) { wxString str = wxGetUserId(); wxStrncpy(name, str, maxlen); name[maxlen-1] = '\0'; return *name > '\0'; } /////////////////////////////////////////////////////////// // TIconizeTaskThread /////////////////////////////////////////////////////////// static bool __bChildRunning = false; class TIconizeTaskThread : public wxThread { protected: virtual ExitCode Entry(); public: TIconizeTaskThread(); }; wxThread::ExitCode TIconizeTaskThread::Entry() { ::wxMilliSleep(500); if (__bChildRunning) // Il programma e' ancora attivo _task_win->Iconize(); return 0; } TIconizeTaskThread::TIconizeTaskThread() { Create(); SetPriority(WXTHREAD_MIN_PRIORITY); Run(); } /////////////////////////////////////////////////////////// // Process processing /////////////////////////////////////////////////////////// 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); TIconizeTaskThread* it = new TIconizeTaskThread(); // No need to delete if (it != NULL) { __bChildRunning = true; exitcode = wxExecute(cmd, wxEXEC_SYNC); __bChildRunning = false; if (_task_win->IsIconized()) _task_win->Restore(); wxEnableTopLevelWindows(TRUE); } } else exitcode = wxExecute(cmd, wxEXEC_SYNC); // Valutare wxEXEC_NODISABLE _task_win->Raise(); } else { if (_task_win != NULL && _task_win_handler != NULL) { wxProcess* p = new wxProcess(_task_win->GetEventHandler(), wxID_ANY); exitcode = wxExecute(cmd, wxEXEC_ASYNC, p); if (exitcode > 0) { XVT_EVENT e(E_PROCESS); e.v.process.msg_id = E_CREATE; e.v.process.pid = exitcode; _task_win_handler((WINDOW)_task_win, &e); } else delete p; } else exitcode = wxExecute(cmd, wxEXEC_ASYNC); } return exitcode; } BOOLEAN xvt_sys_kill(long pid) { BOOLEAN bKilled = wxProcess::Kill(pid, wxSIGTERM, wxKILL_CHILDREN) == wxKILL_OK; if (!bKilled) bKilled = wxProcess::Kill(pid, wxSIGKILL, wxKILL_CHILDREN) == wxKILL_OK; if (bKilled && _task_win != NULL && _task_win_handler != NULL) { XVT_EVENT e(E_PROCESS); e.v.process.msg_id = E_DESTROY; e.v.process.pid = pid; _task_win_handler((WINDOW)_task_win, &e); } return bKilled; } long xvt_sys_execute_in_window(const char* cmdline, WINDOW win) { const long inst = xvt_sys_execute(cmdline, FALSE, FALSE); if (inst > 0 && win != NULL_WIN) { CAST_WIN(win, w); #ifdef __WXMSW__ OsWin32_PlaceProcessInWindow(inst, "", (unsigned int)w.GetHandle()); #else OsLinux_PlaceProcessInWindow(inst, "", w.GetHandle()); #endif } return inst; } long xvt_sys_close_children(WINDOW win) { long c = 0; #ifdef __WXMSW__ CAST_WIN(win, w); c = OsWin32_CloseChildren((unsigned int)w.GetHandle()); #endif return c; } BOOLEAN xvt_sys_goto_url(const char* url, const char* action) { #ifdef __WXMSW__ if (action && *action && xvt_str_compare_ignoring_case(action, "open") != 0) return OsWin32_GotoUrl(url, action); #endif return wxLaunchDefaultBrowser(url); } BOOLEAN xvt_sys_dongle_server_is_running() { wxSingleInstanceChecker sic("Authorization"); return sic.IsAnotherRunning(); } #define OEM_INI wxString(_startup_dir+wxT("/setup/oem.ini")) long xvt_sys_get_oem_int(const char* name, long defval) { static long _oem = -1; if (_oem < 0) _oem = xvt_sys_get_profile_int(OEM_INI, "MAIN", "OEM", -1); if (_oem >= 0) { if (wxStricmp(name, wxT("OEM")) != 0) { wxString strPara; strPara.Printf(wxT("OEM_%d"), _oem); defval = xvt_sys_get_profile_int(OEM_INI, strPara, name, defval); } else defval = _oem; } return defval; } int xvt_sys_get_oem_string(const char* name, const char* defval, char* value, int maxsize) { const int oem = xvt_sys_get_oem_int("OEM", -1); if (oem >= 0) { if (wxStricmp(name, wxT("OEM")) != 0) { wxString strPara; strPara.Printf(wxT("OEM_%d"), oem); return xvt_sys_get_profile_string(OEM_INI, strPara, name, defval, value, maxsize); } else { wxString str; str.Printf("%d", oem); wxStrncpy(value, str, maxsize); return 1; } } return 0; } int xvt_sys_get_profile_string(const char* file, const char* paragraph, const char* name, const char* defval, char* value, int maxsize) { if (file == NULL || *file == '\0') file = xvt_fsys_get_campo_ini(); if (paragraph == NULL || *paragraph == '\0') paragraph = "Main"; #ifdef __WXMSW__ 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; } long xvt_sys_get_profile_int(const char* file, const char* paragraph, const char* name, long defval) { char defstr[16] = "", str[16] = ""; long value = defval; if (defval != 0) wxSprintf(defstr, "%ld", defval); if (xvt_sys_get_profile_string(file, paragraph, name, defstr, str, sizeof(str))) value = atol(str); return value; } BOOLEAN xvt_sys_set_profile_string(const char* file, const char* paragraph, const char* name, const char* value) { if (file == NULL || *file == '\0') file = xvt_fsys_get_campo_ini(); if (paragraph == NULL || *paragraph == '\0') paragraph = "Main"; #ifdef __WXMSW__ 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 __WXMSW__ const wxString e = OsWin32_File2App(file); #else const wxString e = OsLinux_File2App(file); #endif ok = !e.IsEmpty(); if (ok && editor != NULL) wxStrncpy(editor, e, _MAX_PATH); return ok; } int xvt_sys_get_session_id() { #ifdef __WXMSW__ return OsWin32_GetSessionId(); #else return OsLinux_GetSessionId(); #endif } unsigned long xvt_sys_get_free_memory() { const wxMemorySize sz = ::wxGetFreeMemory(); return sz.GetHi() ? -1 : sz.GetLo(); } unsigned long xvt_sys_get_free_memory_kb() { const wxMemorySize sz = ::wxGetFreeMemory() / 1024; // Arrotondo per difetto return sz.GetHi() ? -1 : sz.GetLo(); } int xvt_sys_get_os_version() { int os = 0; #ifdef __WXMSW__ int nVersion = 0; ::GetWinVer(NULL, 0, &nVersion); switch (nVersion) { case 1: case 2: case 3: os = XVT_WS_WIN_95; break; case 4: case 5: case 6: os = XVT_WS_WIN_98; break; case 7: os = XVT_WS_WIN_ME; break; case 101: case 102: os = XVT_WS_WIN_NT; break; case 103: os = XVT_WS_WIN_2000; break; case 104: os = XVT_WS_WIN_XP; break; case 105: os = XVT_WS_WIN_2003; break; case 106: os = XVT_WS_WIN_VISTA; break; case 107: os = XVT_WS_WIN_2008; break; case 108: os = XVT_WS_WIN_2008R2; break; case 109: default : os = XVT_WS_WIN_7; break; } #else os = XVT_WS_LINUX; #endif return os; } BOOLEAN xvt_sys_is_pda() { wxSize sz; if (_task_win == NULL) { sz.x = wxSystemSettings::GetMetric(wxSYS_SCREEN_X); sz.y = wxSystemSettings::GetMetric(wxSYS_SCREEN_Y); } else sz = _task_win->GetSize(); return max(sz.x,sz.y) <= 640; } int xvt_sys_get_version(char* os_version, char* ptk_version, int maxsize) { const int version = xvt_sys_get_os_version(); if (os_version && maxsize >= 8) { #ifdef __WXMSW__ if (version >= XVT_WS_WIN_VISTA) // wxWidgets non sa descrivere i moderni sistemi Microsoft ::GetWinVer(os_version, maxsize, NULL); else #endif wxStrncpy(os_version, wxGetOsDescription(), maxsize); } if (ptk_version && maxsize >= 8) wxStrncpy(ptk_version, wxVERSION_STRING, maxsize); return version; } void xvt_sys_sleep(unsigned long msec) { ::wxMilliSleep(msec); } /////////////////////////////////////////////////////////// // XVT system calls /////////////////////////////////////////////////////////// XVTDLL BOOLEAN xvt_sys_get_env(const char* varname, char* value, int max_size) { const wxString strName(varname); wxString strValue; const bool ok = wxGetEnv(strName, &strValue); if (ok) wxStrncpy(value, strValue, max_size); return ok; } void xvt_sys_searchenv(const char * filename, const char * varname, char * pathname) { DEPRECATED_BOX("xvt_sys_search_env"); xvt_sys_search_env(filename, varname, pathname); } void xvt_sys_search_env(const char * filename, const char * varname, char * pathname) { #ifdef __WXMSW__ _searchenv(filename, varname, pathname); #else const char * value = wxGetEnv(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_sys_set_env(const char* varname, const char* value) { const wxString strName(varname); return value != NULL ? wxSetEnv(strName, value) : wxUnsetEnv(strName); } // BOOLEAN o int? Adso! int xvt_fsys_access(const char *pathname, int mode) { return wxAccess(pathname, mode) == -1 ? errno : 0; } BOOLEAN xvt_fsys_file_exists(const char *pathname) { return xvt_fsys_file_attr(pathname, XVT_FILE_ATTR_EXIST); } BOOLEAN xvt_fsys_mkdir(const char *pathname) { // Crea l'intero albero di cartelle senza dare erroire se esistono gia' return wxFileName::Mkdir(pathname, 0777, wxPATH_MKDIR_FULL); } BOOLEAN xvt_fsys_rmdir(const char *pathname) { if (!wxDirExists(pathname)) return TRUE; return wxRmdir(pathname); } BOOLEAN xvt_fsys_remove_file(const char *pathname) { return wxRemoveFile(pathname); } BOOLEAN xvt_fsys_removefile(const char *pathname) { DEPRECATED_BOX("xvt_fsys_remove_file"); return xvt_fsys_remove_file(pathname); } BOOLEAN xvt_fsys_rename_file(const char *src_pathname, const char *dst_pathname) { return wxRenameFile(src_pathname, dst_pathname); } /////////////////////////////////////////////////////////// // Timers /////////////////////////////////////////////////////////// struct tm* xvt_time_now() { return wxDateTime::GetTmNow(); } 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 /////////////////////////////////////////////////////////// static wxWindow* SafeCastWin(WINDOW win) { wxWindow* w = wxDynamicCast(_nice_windows.Get(win), wxWindow); if (w != NULL) { wxASSERT(win == (WINDOW)w); const TwxWindow* tw = wxDynamicCast(w, TwxWindow); if (tw != NULL && tw->InDestroy()) w = NULL; } return w; } void xvt_vobj_destroy(WINDOW win) { wxWindow* w = SafeCastWin(win); if (w != NULL) { xvt_win_set_caret_visible(win, FALSE); w->Destroy(); // same as delete w _nice_windows.Delete(win); // Elimina "di nuovo" dalla lista delle finestre attive } } static long xvt_vobj_get_metric(WINDOW win, wxSystemMetric data) { wxWindow* w = wxDynamicCast((wxObject*)win, wxWindow); if (w == NULL) w = _task_win; long ret = wxSystemSettings::GetMetric(data, w); return ret; } 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)*16); if (win != NULL_WIN && win != SCREEN_WIN) { TTaskWin* tw = wxDynamicCast(_task_win, TTaskWin); if (tw != NULL) { const XVT_COLOR_COMPONENT* tcc = tw->GetCtlColors(); int c = 0; for (c = 0; c < 15 && tcc[c].type != XVT_COLOR_NULL; c++); memcpy(xcc, tcc, (c+1)*sizeof(XVT_COLOR_COMPONENT)); return long(xcc); } } // XVT components 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_BLEND; xcc[2].color = MAKE_XVT_COLOR(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNHIGHLIGHT)); xcc[3].type = XVT_COLOR_BORDER; xcc[3].color = MAKE_XVT_COLOR(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW)); xcc[4].type = XVT_COLOR_SELECT; xcc[4].color = MAKE_XVT_COLOR(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT)); xcc[5].type = XVT_COLOR_HIGHLIGHT; xcc[5].color = MAKE_XVT_COLOR(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT)); xcc[6].type = XVT_COLOR_TROUGH; xcc[6].color = MAKE_XVT_COLOR(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); // AGA components xcc[7].type = XVT_COLOR_CAPTIONLT; xcc[7].color = MAKE_XVT_COLOR(wxSystemSettings::GetColour(wxSYS_COLOUR_ACTIVECAPTION)); xcc[8].type = XVT_COLOR_CAPTIONDK; xcc[8].color = MAKE_XVT_COLOR(wxSystemSettings::GetColour(wxSYS_COLOUR_INACTIVECAPTION)); xcc[9].type = XVT_COLOR_CAPTIONTEXT; xcc[9].color = MAKE_XVT_COLOR(wxSystemSettings::GetColour(wxSYS_COLOUR_CAPTIONTEXT)); // Ensure last (NULL) component xcc[15].type = XVT_COLOR_NULL; xcc[15].color = 0; ret = (long)xcc; } break; case ATTR_APPL_VERSION_STRING: ret = (long)(const char*)_appl_version; break; case ATTR_DOCFRAME_WIDTH: case ATTR_FRAME_WIDTH: ret = xvt_vobj_get_metric(win, wxSYS_FRAMESIZE_X); break; case ATTR_DOCFRAME_HEIGHT: case ATTR_FRAME_HEIGHT: ret = xvt_vobj_get_metric(win, wxSYS_FRAMESIZE_Y); break; case ATTR_MENU_HEIGHT: ret = xvt_vobj_get_metric(win, wxSYS_MENU_Y); break; case ATTR_TITLE_HEIGHT: ret = xvt_vobj_get_metric(win, wxSYS_CAPTION_Y); 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()) // Test ormai ridicolo? { case 1: ret = XVT_DISPLAY_MONO; break; // Ridicolissimo :-) 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: { const wxWindow* w = SafeCastWin(win); if (w != NULL) ret = (long)w->GetHandle(); } break; case ATTR_PRINTER_HEIGHT: xvt_app_escape(XVT_ESC_GET_PRINTER_INFO, NULL, &ret, NULL, NULL, NULL); break; case ATTR_PRINTER_HRES: xvt_app_escape(XVT_ESC_GET_PRINTER_INFO, NULL, NULL, NULL, NULL, &ret); break; case ATTR_PRINTER_VRES: xvt_app_escape(XVT_ESC_GET_PRINTER_INFO, NULL, NULL, NULL, &ret, NULL); break; case ATTR_PRINTER_WIDTH: xvt_app_escape(XVT_ESC_GET_PRINTER_INFO, NULL, NULL, &ret, NULL, NULL); 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 = xvt_dm_speech_enabled(); 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; case ATTR_WIN_PM_TWIN_STARTUP_STYLE: ret = _startup_style; break; case ATTR_ICON_WIDTH: ret = xvt_vobj_get_metric(win, wxSYS_ICON_X); break; case ATTR_ICON_HEIGHT: ret = xvt_vobj_get_metric(win, wxSYS_ICON_Y); 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) { const TwxWindow* w = wxDynamicCast(SafeCastWin(win), TwxWindow); return w != NULL ? w->_app_data : 0L; } RCT* xvt_vobj_get_outer_rect(WINDOW win, RCT *rctp) { if (win != NULL_WIN) { if (win == SCREEN_WIN) { const short sx = wxSystemSettings::GetMetric(wxSYS_SCREEN_X); const short sy = wxSystemSettings::GetMetric(wxSYS_SCREEN_Y); xvt_rect_set(rctp, 0, 0, sx, sy); } else { CAST_WIN(win, w); const wxRect rct = w.GetRect(); Rect2RCT(rct, rctp); } } else xvt_rect_set_null(rctp); return rctp; } XVT_PALETTE xvt_vobj_get_palet(WINDOW WXUNUSED(win)) { return NULL; } WINDOW xvt_vobj_get_parent(WINDOW win) { if (win == NULL_WIN || 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); wxStrncpy(title, w.GetLabel(), sz_title); title[sz_title-1] = '\0'; return title; } WIN_TYPE xvt_vobj_get_type(WINDOW win) { if (win == NULL_WIN) return W_NONE; if (win == TASK_WIN) return W_TASK; if (win == SCREEN_WIN) return W_SCREEN; if (win == PRINTER_WIN) return W_PRINT; TwxWindow* w = wxDynamicCast((wxObject*)win, TwxWindow); if (w != NULL) return w->_type; return WO_TE; // Unknown custom control } BOOLEAN xvt_vobj_is_focusable(WINDOW win) { BOOLEAN ok = win != NULL_WIN && win != PRINTER_WIN && xvt_vobj_is_valid(win); if (ok) { CAST_WIN(win, w); ok = w.IsEnabled() && w.IsShownOnScreen(); } return ok; } BOOLEAN xvt_vobj_is_valid(WINDOW win) { return win != NULL_WIN && SafeCastWin(win) != NULL; } void xvt_vobj_maximize(WINDOW win) { XVT_ASSERT(win != NULL_WIN && _task_win != NULL); if (win == TASK_WIN) _task_win->Maximize(); else { CAST_WIN(win, w); wxWindow* parent = w.GetParent(); if (parent == NULL) parent = _task_win; int width, height; parent->GetClientSize(&width, &height); w.SetSize(0, 0, width, height); } } void xvt_vobj_minimize(WINDOW win) { wxFrame* pMain = wxDynamicCast((wxObject*)win, wxFrame); if (pMain != NULL) pMain->Iconize(); else SORRY_BOX(); } void xvt_vobj_move(WINDOW win, const RCT* rctp) { CAST_WIN(win, w); const wxRect rct = RCT2Rect(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(); } static void SetArtistColor(WINDOW win, int id, long rgb) { CAST_WIN(win, w); const wxAuiManager* pMgr = wxAuiManager::GetManager(&w); wxAuiDockArt* pArt = (pMgr != NULL) ? pMgr->GetArtProvider() : NULL; if (pArt != NULL) { CAST_COLOR(rgb, col); pArt->SetColour(id, col); if (id == wxAUI_DOCKART_BACKGROUND_COLOUR) { } } } void xvt_vobj_set_attr(WINDOW win, long data, long value) { switch (data) { case ATTR_APP_CTL_COLORS: if (win == TASK_WIN) { TTaskWin* tw = wxDynamicCast(_task_win, TTaskWin); if (tw != NULL) tw->SetCtlColors((XVT_COLOR_COMPONENT*)value); } break; case ATTR_APPL_VERSION_STRING: _appl_version = (const char*)value; break; case ATTR_BACK_COLOR: SetArtistColor(win, wxAUI_DOCKART_BACKGROUND_COLOUR, value); break; 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: _startup_style = value; break; case ATTR_SPEECH_MODE: xvt_dm_speech_enable(value); break; default: SORRY_BOX(); break; } } void xvt_vobj_set_data(WINDOW win, long app_data) { CAST_TWIN(win, w); w._app_data = app_data; } void xvt_vobj_set_enabled(WINDOW win, BOOLEAN enabled) { CAST_WIN(win, w); w.Enable(enabled != 0); } void xvt_vobj_set_palet(WINDOW WXUNUSED(win), XVT_PALETTE WXUNUSED(palet)) { // Do not implement! } void xvt_vobj_set_title(WINDOW win, const char* title) { CAST_WIN(win, w); w.SetLabel(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 WXUNUSED(mask), EVENT_HANDLER eh, long app_data) { const wxRect rct = RCT2Rect(rct_p); const wxString caption = title; long style = wxCLIP_SIBLINGS | wxCLIP_CHILDREN | wxWANTS_CHARS; if (win_flags & WSF_VSCROLL) style |= wxVSCROLL; if (win_flags & WSF_HSCROLL) style |= wxHSCROLL; TwxWindow* w = NULL; switch (wtype) { case W_DOC: style |= wxSYSTEM_MENU; // Questo flag in realta' viene interpretato come wxCAPTION if (win_flags & WSF_CLOSE) style |= wxCLOSE_BOX; 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, rct.GetPosition(), rct.GetSize(), style); w->_type = wtype; w->_app_data = app_data; w->SetBackgroundStyle(wxBG_STYLE_CUSTOM); // Lo sfondo viene disegnato nella OnPaint #ifdef __WXMSW__ OsWin32_SetCaptionStyle(w->GetHWND(), style); #else OsLinux_SetCaptionStyle(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); 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); xvt_vobj_move((WINDOW)w, rct_p); // Forza la giusta dimensione della client area return (WINDOW)w; } long xvt_win_dispatch_event(WINDOW win, EVENT* event_p) { XVT_ASSERT(win != NULL_WIN && event_p != NULL); if (win == (WINDOW)_task_win) return _task_win_handler(win, event_p); CAST_TWIN(win, w); return w._eh(win, event_p); } BOOLEAN xvt_win_enum_wins(WINDOW parent_win, XVT_ENUM_CHILDREN func, long data, unsigned long /*reserved*/) { CAST_WIN(parent_win, w) wxWindowList& list = w.GetChildren(); const BOOLEAN ok = list.GetCount() > 0; if (ok && func != NULL) { for (wxWindowList::iterator i = list.begin(); i != list.end(); ++i) { wxWindow* tw = wxDynamicCast(*i, wxWindow); if (tw != NULL) { if (!func((WINDOW)tw, data)) break; } } } return ok; } long xvt_win_get_children_count(WINDOW parent_win) { long nCount = 0; if (parent_win != NULL_WIN) { CAST_WIN(parent_win, w) #ifdef __WXMSW__ nCount = OsWin32_GetChildrenCount((unsigned int)w.GetHandle()); #else nCount = w.GetChildren().GetCount(); #endif } return nCount; } void xvt_win_post_event(WINDOW win, EVENT* event_p) { // Per ora e' garantito che funzioni solo con la task window CAST_WIN(win, w); switch (event_p->type) { case E_COMMAND: { wxCommandEvent e(wxEVT_COMMAND_MENU_SELECTED, event_p->v.cmd.tag); e.SetEventObject(&w); wxPostEvent(&w, 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 = wxWindow::GetCapture(); if (cap != NULL) cap->ReleaseMouse(); _mouse_trapper = NULL; } } void xvt_win_set_cursor(WINDOW win, CURSOR cursor) { CAST_WIN(win, w); wxCursor cur; switch (cursor) { case CURSOR_ARROW: cur = *wxSTANDARD_CURSOR; break; case CURSOR_CROCE: cur = *wxCROSS_CURSOR; break; case CURSOR_WAIT : cur = *wxHOURGLASS_CURSOR; break; default: cur = xvtart_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 /////////////////////////////////////////////////////////// static wxStatusBar* WIN2StatBar(WINDOW win) { wxStatusBar* pStatusBar = NULL; if (win == NULL_WIN || win == TASK_WIN) pStatusBar = _task_win->GetStatusBar(); else pStatusBar = wxDynamicCast((wxObject*)win, wxStatusBar); return pStatusBar; } const char* statbar_set_title(WINDOW win, const char* text) { wxStatusBar* pStatusBar = WIN2StatBar(win); if (pStatusBar != NULL) { if (text == NULL) text = _strDefaultStatbarText; wxStringTokenizer tok(text, "\t", wxTOKEN_RET_EMPTY); for (int t = 0; tok.HasMoreTokens(); t++) { const wxString strMsg = tok.GetNextToken(); pStatusBar->SetStatusText(strMsg, t); if (t == 0) pStatusBar->SetToolTip(strMsg); } } return text; } const char* statbar_set_default_title(WINDOW win, const char *text) { _strDefaultStatbarText = text; return statbar_set_title(win, text); } XVT_FNTID statbar_set_fontid(WINDOW win, XVT_FNTID font_id) { wxStatusBar* pStatBar = WIN2StatBar(win); if (pStatBar != NULL && font_id != NULL) { CAST_FONT(font_id, font); pStatBar->SetFont(font.Font(NULL, win)); } return font_id; } XVT_FNTID statbar_get_fontid(WINDOW win, XVT_FNTID font_id) { wxStatusBar* pStatBar = WIN2StatBar(win); if (pStatBar != NULL && font_id != NULL) { CAST_FONT(font_id, font); font.Copy(pStatBar->GetFont()); } return font_id; } WINDOW statbar_create(int cid, int WXUNUSED(left), int WXUNUSED(top), int WXUNUSED(right), int WXUNUSED(bottom), int WXUNUSED(prop_count), char** WXUNUSED(prop_list), WINDOW parent_win, int WXUNUSED(parent_rid), long WXUNUSED(parent_flags), char* WXUNUSED(parent_class)) { wxStatusBar* pStatusBar = NULL; wxFrame* w = wxDynamicCast(SafeCastWin(parent_win), wxFrame); if (w != NULL) { const int nStyle = 0; // not wxST_SIZEGRIP pStatusBar = w->CreateStatusBar(3, nStyle, cid); if (pStatusBar != NULL) { const int widths[4] = { -4, -2, -2, 0 }; pStatusBar->SetStatusWidths(3, widths); } } return (WINDOW)pStatusBar; } BOOLEAN statbar_destroy(WINDOW win) { wxStatusBar* pStatusBar = WIN2StatBar(win); if (pStatusBar != NULL) { if (_task_win->GetStatusBar() == pStatusBar) _task_win->SetStatusBar(NULL); pStatusBar->Destroy(); } return pStatusBar != NULL; }