4505 lines
		
	
	
		
			110 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			4505 lines
		
	
	
		
			110 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #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 <wx/artprov.h>
 | ||
| #include <wx/aui/aui.h>
 | ||
| #include <wx/clipbrd.h>
 | ||
| #include <wx/dialup.h>
 | ||
| #include <wx/fileconf.h>
 | ||
| #include <wx/filefn.h>
 | ||
| #include <wx/filename.h>
 | ||
| #include <wx/image.h>
 | ||
| #include <wx/protocol/ftp.h>
 | ||
| #include <wx/protocol/http.h>
 | ||
| #include <wx/snglinst.h>
 | ||
| #include <wx/sysopt.h>
 | ||
| #include <wx/thread.h>
 | ||
| #include <wx/tokenzr.h>
 | ||
| #include <wx/url.h>
 | ||
| #include <wx/wfstream.h>
 | ||
| 
 | ||
| #include <errno.h>
 | ||
| 
 | ||
| #if wxCHECK_VERSION(2,9,0)
 | ||
| #include <wx/propgrid.h>
 | ||
| #else
 | ||
| #include <wx/propgrid/propgrid.h>
 | ||
| #endif
 | ||
| 
 | ||
| 
 | ||
| #ifdef __WXMSW__
 | ||
| #include "oswin32.h"
 | ||
| #include "XFont.h"
 | ||
| #else
 | ||
| #include <errno.h>
 | ||
| #include <unistd.h>
 | ||
| #include "oslinux.h"
 | ||
| #include <wx/dcps.h>
 | ||
| #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;
 | ||
| BOOLEAN   _appl_already_running;
 | ||
| wxLocale* _locale = NULL;
 | ||
| 
 | ||
| static XVT_ERRMSG_HANDLER _error_handler = NULL;
 | ||
| 
 | ||
| const wxString& _GetAppTitle()
 | ||
| { 
 | ||
|   if (_appl_name.IsEmpty())
 | ||
|   {
 | ||
|     const wxFileName fn = __argv[0];
 | ||
|     _appl_name << "CAMPO: " << fn.GetName();
 | ||
|   }
 | ||
|   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<47> 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
 | ||
| }
 | ||
| 
 | ||
| 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;
 | ||
| 
 | ||
| #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);   
 | ||
|   }
 | ||
| #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
 | ||
|   {
 | ||
| 		style |= wxMAXIMIZE;
 | ||
|   }
 | ||
| 
 | ||
|   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[4] = { NULL };
 | ||
|   wxString Title[4];
 | ||
|   Title[0] = "&File";
 | ||
|   Menus[0] = new wxMenu;
 | ||
|   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_HELP_VERSION, "Storia delle &modifiche");
 | ||
|   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();
 | ||
| 
 | ||
|   xvt_dm_speech_enable(0x00);
 | ||
| 
 | ||
|   xvt_sign_stop();
 | ||
| 
 | ||
|   if (_locale != NULL)
 | ||
|   {
 | ||
|     delete _locale;
 | ||
|     _locale = NULL;
 | ||
|   }
 | ||
| 
 | ||
| #ifdef __WXMSW__
 | ||
|   // Evita noiosa finestra d'errore che succede solo a PressColor
 | ||
|   ::SetErrorMode(SEM_NOGPFAULTERRORBOX);
 | ||
| #endif
 | ||
| }
 | ||
| 
 | ||
| DRAW_CTOOLS* xvt_app_get_default_ctools(DRAW_CTOOLS *ct)
 | ||
| {	
 | ||
| 	XVT_ASSERT(ct != NULL);
 | ||
| 	TDC dc(NULL);
 | ||
| 	memcpy(ct, &dc._dct, sizeof(DRAW_CTOOLS));
 | ||
| 	return ct;
 | ||
| }
 | ||
| 
 | ||
| void xvt_app_process_pending_events(void)
 | ||
| {
 | ||
|   wxApp* a = wxTheApp;  // Memorizzo il risultato di wxGetInstance
 | ||
|   if (a != NULL)        // 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)
 | ||
| { return FALSE; }
 | ||
| 
 | ||
| BOOLEAN xvt_dongle_hl_login(unsigned short address, const unsigned char* label, const unsigned char* password)
 | ||
| { return FALSE; }
 | ||
| 
 | ||
| BOOLEAN xvt_dongle_hl_logout()
 | ||
| { return FALSE; }
 | ||
| 
 | ||
| BOOLEAN  xvt_dongle_hl_read(unsigned short reg, unsigned short* data)
 | ||
| { return FALSE; }
 | ||
| 
 | ||
| BOOLEAN xvt_dongle_hl_read_block(unsigned char* data)
 | ||
| { return FALSE; }
 | ||
| 
 | ||
| BOOLEAN xvt_dongle_hl_write(unsigned short reg, unsigned short data)
 | ||
| { return FALSE; }
 | ||
| 
 | ||
| BOOLEAN xvt_dongle_sl_crypt(unsigned short* data)
 | ||
| { return FALSE; }
 | ||
| 
 | ||
| BOOLEAN xvt_dongle_sl_login(const unsigned char* label, const unsigned char* password)
 | ||
| { return FALSE; }
 | ||
| 
 | ||
| BOOLEAN xvt_dongle_sl_logout()
 | ||
| { return FALSE; }
 | ||
| 
 | ||
| BOOLEAN xvt_dongle_sl_read_block(unsigned short reg, unsigned short size, unsigned short* data)
 | ||
| { return FALSE; }
 | ||
| 
 | ||
| BOOLEAN xvt_dongle_sl_write_block(unsigned short reg, unsigned short size, const unsigned short* data)
 | ||
| { return FALSE; }
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // Font cache
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| 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_checkmark(WINDOW win, const RCT* rctp)
 | ||
| {
 | ||
|   CAST_DC(win, dc);
 | ||
| 	const wxRect rct = RCT2Rect(rctp);
 | ||
| 	dc.DrawCheckMark(rct);
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 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-ico.GetWidth())/2, rct->top+(h-ico.GetHeight())/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();
 | ||
|   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, const 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__
 | ||
|   CAST_DC(win, dc);
 | ||
|   OsWin32_DrawDottedRect(dc.GetHDC(), rctp->left, rctp->top, rctp->right, rctp->bottom);
 | ||
| #else
 | ||
|   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);
 | ||
| #endif
 | ||
| }
 | ||
| 
 | ||
| void xvt_dwin_draw_set_pos(WINDOW win, PNT pnt)
 | ||
| {
 | ||
| 	CAST_TDC(win, dc);
 | ||
| 	dc._pnt.x = pnt.h;
 | ||
| 	dc._pnt.y = pnt.v;
 | ||
| }
 | ||
| 
 | ||
| // x refers to to the left of the text
 | ||
| // y refers to the baseline of the text
 | ||
| // s is the text
 | ||
| // len is the klenght of the text (-1 stands for all the null terminated text)
 | ||
| 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!
 | ||
| /*
 | ||
| #ifndef NDEBUG
 | ||
|       // Disegna linee base del testo 
 | ||
|       int width = ::xvt_dwin_get_text_width(win, s, len);
 | ||
|       int leading, ascent, descent; xvt_dwin_get_font_metrics(win, &leading, &ascent, &descent);
 | ||
| 
 | ||
|       dc.SetPen(*wxMEDIUM_GREY_PEN);
 | ||
|       dc.DrawLine(x, y, x+width, y);
 | ||
| 
 | ||
|       dc.SetPen(*wxCYAN_PEN);
 | ||
|       dc.DrawLine(x, y-ascent, x+width, y-ascent);
 | ||
| 
 | ||
|       dc.SetPen(*wxGREEN_PEN);
 | ||
|       dc.DrawLine(x, y+descent, x+width, y+descent);
 | ||
| 
 | ||
|       if (leading > 0)
 | ||
|       {
 | ||
|         dc.SetPen(*wxRED_PEN);
 | ||
|         dc.DrawLine(x, y+descent+leading, x+width, y+descent+leading);
 | ||
|       }
 | ||
| #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 = "Kpfx";
 | ||
| 	int height, desc, lead;
 | ||
|   dc.GetTextExtent(str, NULL, &height, &desc, &lead);
 | ||
| 	if (leadingp)
 | ||
| 		*leadingp = lead;
 | ||
|   if (ascentp)
 | ||
|     *ascentp = height-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 = "Kpfx";
 | ||
| 	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; //*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);
 | ||
| }
 | ||
| 
 | ||
| void xvt_fsys_get_temp_dir(DIRECTORY *dirp)
 | ||
| {
 | ||
|   xvt_sys_get_profile_string(NULL, "Main", "Temp", "", dirp->path, sizeof(dirp->path));
 | ||
|   if (!*dirp->path)
 | ||
|     wxStrcpy(dirp->path, wxFileName::GetTempDir());
 | ||
| }
 | ||
| 
 | ||
| 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)
 | ||
|   {
 | ||
|     const wxString strRoot = get_disk_root(path);
 | ||
|     yes = ::GetDriveType(strRoot) == DRIVE_REMOVABLE;
 | ||
|   }
 | ||
|   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
 | ||
|     {
 | ||
|       const wxString strRoot = get_disk_root(path);
 | ||
|       yes = ::GetDriveType(strRoot) == DRIVE_REMOTE;
 | ||
|     }
 | ||
|   }
 | ||
|   return yes;
 | ||
| }
 | ||
| 
 | ||
| BOOLEAN xvt_fsys_is_fixed_drive(const char* path)
 | ||
| {
 | ||
|   BOOLEAN yes = FALSE;
 | ||
|   if (path && *path)
 | ||
|   {
 | ||
|     if (!wxIsPathSeparator(path[0]) || !wxIsPathSeparator(path[1]))
 | ||
|     {
 | ||
|       const wxString strRoot = get_disk_root(path);
 | ||
|       yes = ::GetDriveType(strRoot) == DRIVE_FIXED;
 | ||
|     }
 | ||
|   }
 | ||
|   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)
 | ||
|   {
 | ||
|     switch (attr)
 | ||
|     {
 | ||
|     case XVT_FILE_ATTR_EXIST: 
 | ||
|       ret = xvt_fsys_access(path, 0) == 0;
 | ||
|       break;
 | ||
|     case XVT_FILE_ATTR_READ: 
 | ||
|       ret = xvt_fsys_access(path, 1) == 0;
 | ||
|       break;
 | ||
|     case XVT_FILE_ATTR_WRITE: 
 | ||
|       ret = xvt_fsys_access(path, 2) == 0;
 | ||
|       break;
 | ||
|     case XVT_FILE_ATTR_DIRECTORY:
 | ||
|       ret = ::wxDirExists(path);
 | ||
|       break;
 | ||
|     case XVT_FILE_ATTR_SIZE:
 | ||
|       {
 | ||
| 				wxURL url(path);
 | ||
| 				wxString scheme = url.GetScheme();
 | ||
| 
 | ||
| 				if (scheme == "ftp" || scheme == "http")
 | ||
| 				{
 | ||
| 					SLIST files = xvt_fsys_list_files("", path, false);
 | ||
| 					const int count = xvt_slist_count(files);
 | ||
| 					
 | ||
| 					if (count > 0)
 | ||
| 					{
 | ||
| 						SLIST_ELT e = xvt_slist_get_first(files);
 | ||
| 						ret = e->data;
 | ||
| 					}
 | ||
| 					else
 | ||
| 						ret = -1L;
 | ||
| 					xvt_slist_destroy(files);
 | ||
| 					return ret;
 | ||
| 				}
 | ||
|         const wxULongLong sz = wxFileName::GetSize(path);
 | ||
|         ret = sz.GetHi() != 0 ? INT_MAX : sz.GetLo();
 | ||
|       }
 | ||
|       break;
 | ||
|     case XVT_FILE_ATTR_MTIME:
 | ||
|       ret = ::wxFileModificationTime(path);
 | ||
|       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
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| static bool xvt_sys_ftp_passive_mode(const char* server)
 | ||
| {
 | ||
|   static char pasv = ' ';
 | ||
|   if (pasv <= ' ')
 | ||
|   {
 | ||
|     char str[16] = "";
 | ||
|     xvt_sys_get_profile_string(xvt_fsys_get_campo_ini(), "Server", "ftp", "Passive", str, sizeof(str));
 | ||
|     pasv = toupper(str[0]);
 | ||
|   }
 | ||
|   return pasv != 'A';
 | ||
| }
 | ||
| 
 | ||
| SLIST xvt_fsys_list_files(const char *type, const char *pat, BOOLEAN dirs)
 | ||
| {
 | ||
|   wxBusyCursor hourglass;
 | ||
| 	
 | ||
|   SLIST list = xvt_slist_create();
 | ||
| 
 | ||
|   int flags = wxFILE | wxDIR;
 | ||
| 	if (dirs)
 | ||
| 	{
 | ||
| 		if (xvt_str_same(type, DIR_TYPE))
 | ||
| 	    flags = wxDIR;
 | ||
| 	}
 | ||
| 	else
 | ||
| 		flags = wxFILE;
 | ||
| 
 | ||
| 	const wxURL url(pat);
 | ||
| 	if (url.GetScheme() == "ftp")
 | ||
| 	{
 | ||
| 		const wxString strHost  = url.GetServer();
 | ||
|     const wxString strUser  = url.GetUser();
 | ||
|     const wxString strPwd   = url.GetPassword();
 | ||
|     const wxFileName fnPath = url.GetPath();
 | ||
| 		const wxString fnDir    = fnPath.GetPath(wxPATH_GET_VOLUME, wxPATH_UNIX);
 | ||
| 		const wxString fnName   = fnPath.GetFullName();
 | ||
| 		
 | ||
|     wxFTP ftp;
 | ||
| 
 | ||
|     if (!strUser.IsEmpty())
 | ||
|     {
 | ||
|       ftp.SetUser(strUser);
 | ||
|       ftp.SetPassword(strPwd);
 | ||
|     }
 | ||
|     ftp.SetPassive(xvt_sys_ftp_passive_mode(strHost));
 | ||
| 
 | ||
|     const bool bConnected = ftp.Connect(strHost);
 | ||
|     if (bConnected && ftp.ChDir(fnDir))
 | ||
| 		{      
 | ||
|       wxString RemotePath = pat;
 | ||
| 	  	RemotePath = RemotePath.BeforeLast('/');
 | ||
| 			
 | ||
|       wxArrayString files;
 | ||
| 			ftp.GetList(files, fnName, true);
 | ||
| 
 | ||
| 			for (size_t i = 0; i < files.GetCount(); i++)
 | ||
| 			{
 | ||
| 				const int type = files[i][0] == 'd' ? wxDIR : wxFILE;
 | ||
| 				if (type & flags) // Entry type matches desired mask?
 | ||
| 				{
 | ||
| 					wxString f = RemotePath; f << '/' << files[i].AfterLast(' ');
 | ||
| 					wxString size = files[i].Mid(30);
 | ||
| 					xvt_slist_add_at_elt(list, NULL, f, type == wxFILE ? wxAtol(size) : -1L);
 | ||
| 				}
 | ||
| 			}
 | ||
| 	  }
 | ||
|   }
 | ||
|   else  //normale list_files
 | ||
|   {
 | ||
|     wxString ext;
 | ||
|     if (flags == wxFILE)
 | ||
|       wxSplitPath(pat, NULL, NULL, &ext);
 | ||
| 
 | ||
|     wxString f = ::wxFindFirstFile(pat, flags);
 | ||
|     while (!f.IsEmpty())
 | ||
| 	  {
 | ||
|       if (f.StartsWith(".\\") || f.StartsWith("./"))
 | ||
|         f = f.Mid(2);
 | ||
| 
 | ||
|       bool bGood = true;
 | ||
|       if (flags == wxFILE && ext.Len() >= 3)
 | ||
|         bGood = wxStricmp(ext, f.AfterLast('.')) == 0;
 | ||
|       if (bGood)
 | ||
|         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);
 | ||
| }
 | ||
| 
 | ||
| BOOLEAN xvt_fsys_fcopy(const char* orig, const char* dest)
 | ||
| { 
 | ||
| 	wxURL orig_url(orig);
 | ||
| 
 | ||
|   wxInputStream* input = NULL;
 | ||
|   if (orig_url.HasScheme())
 | ||
|   {
 | ||
|     if (orig_url.GetScheme() == "ftp")
 | ||
|     {
 | ||
|       wxFTP& ftp = *wxStaticCast(&orig_url.GetProtocol(),  wxFTP);
 | ||
|       ftp.SetPassive(xvt_sys_ftp_passive_mode(orig_url.GetServer()));
 | ||
|     }
 | ||
|     input = orig_url.GetInputStream();
 | ||
|   }
 | ||
|   else
 | ||
| 		input = new wxFileInputStream(orig);
 | ||
|  
 | ||
|   if (input == NULL)
 | ||
|     return FALSE;
 | ||
|   	
 | ||
| 	wxURL dest_url(dest);
 | ||
|   wxOutputStream* output = NULL;
 | ||
| 	const wxString scheme = dest_url.GetScheme();
 | ||
| 
 | ||
| 	if (scheme == "ftp")
 | ||
| 	{
 | ||
| 	  wxFTP ftp;
 | ||
|     const wxString strHost = dest_url.GetServer();
 | ||
|     const wxString strUser = dest_url.GetUser();
 | ||
|     const wxString strPwd = dest_url.GetPassword();
 | ||
|     const wxFileName fnPath = dest_url.GetPath();
 | ||
| 		const wxString  fnDir = fnPath.GetPath(wxPATH_GET_VOLUME, wxPATH_UNIX);
 | ||
| 		const wxString  fnName = fnPath.GetFullName();
 | ||
| 
 | ||
|     if (!strUser.IsEmpty())
 | ||
|     {
 | ||
|       ftp.SetUser(strUser);
 | ||
|       ftp.SetPassword(strPwd);
 | ||
|     }
 | ||
|     ftp.SetPassive(xvt_sys_ftp_passive_mode(strHost));
 | ||
|   
 | ||
|     if (ftp.Connect(strHost) && ftp.SetBinary() && ftp.ChDir(fnDir))
 | ||
|   		output = ftp.GetOutputStream(fnName);
 | ||
| 	}
 | ||
| 	else
 | ||
|   {
 | ||
| 		if (scheme == "http")
 | ||
| 			return false;
 | ||
| 		else
 | ||
| 			output = new wxFileOutputStream(dest);
 | ||
|   }
 | ||
| 
 | ||
| 	BOOLEAN ok = FALSE;
 | ||
| 	if (input != NULL && output != NULL)
 | ||
| 	{
 | ||
| 		input->Read(*output);
 | ||
| 		wxStreamError err = output->GetLastError();
 | ||
| 		ok = (err == wxSTREAM_NO_ERROR);
 | ||
|     output->Close();
 | ||
| 	}
 | ||
| 	if (input != NULL)
 | ||
|  		delete input;
 | ||
| 	if (output != NULL && scheme != "ftp")
 | ||
| 		delete output;
 | ||
| 	return ok;
 | ||
| }
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // Images
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| inline bool XVT_SAME_COLOR(COLOR col1, COLOR col2) { return (col1 & 0x00FFFFFF) == (col2 & 0x00FFFFFF); }
 | ||
| 
 | ||
| void xvt_image_blur(XVT_IMAGE img, short radius)
 | ||
| {
 | ||
| 	CAST_TIMAGE(img, image);
 | ||
|   image->Blur(radius);
 | ||
| }
 | ||
| 
 | ||
| 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);
 | ||
| 
 | ||
|   CAST_DC(win, wdc);
 | ||
| 
 | ||
|   wxBitmap bmp(r.GetWidth(), r.GetHeight());
 | ||
|   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;
 | ||
| 	const wxString name = filenamep;
 | ||
| 	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);
 | ||
| 
 | ||
|     const wxRect rctDstI(0, 0, dst->GetWidth(), dst->GetHeight());
 | ||
|     const wxRect rctSrcI(0, 0, src->GetWidth(), src->GetHeight());
 | ||
|     
 | ||
|     if (rctDst.GetSize() == rctSrc.GetSize() && 
 | ||
|         rctDstI.Contains(rctDst) && rctSrcI.Contains(rctSrc) && 
 | ||
|         src->HasAlpha() == dst->HasAlpha())
 | ||
|     {
 | ||
|       const int nPixelSize = src->HasAlpha() ? 4 : 3;
 | ||
|       const int nRowSize = nPixelSize * src->GetWidth();
 | ||
| #ifndef NDEBUG
 | ||
|       #pragma omp parallel for
 | ||
| #endif
 | ||
|       for (int y = 0; y < rctSrc.height; y++)
 | ||
|       {
 | ||
|         unsigned char* rgbSrc = src->Image().GetData() + (rctSrc.y+y)*nRowSize + rctSrc.x * nPixelSize;
 | ||
|         unsigned char* rgbDst = dst->Image().GetData() + (rctDst.y+y)*nRowSize + rctDst.x * nPixelSize;
 | ||
|         memcpy(rgbDst, rgbSrc, nPixelSize * rctSrc.width);
 | ||
|       }
 | ||
|     }
 | ||
|     else
 | ||
|     {
 | ||
|       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;
 | ||
|       const int nRowSize = nPixelSize * img->GetWidth();
 | ||
|       for (short y = 0; y < h; y++)
 | ||
|       {
 | ||
|         unsigned char* rgb = img->Image().GetData() + nRowSize*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)
 | ||
| {
 | ||
|   XVT_IMAGE img = NULL;
 | ||
|   const wxIcon icon = xvtart_GetIconResource(rid);
 | ||
|   if (icon.IsOk())
 | ||
|   {
 | ||
|     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.SetBackground(*wxWHITE_BRUSH); 
 | ||
|       dc.Clear();
 | ||
|       dc.DrawIcon(icon, 0, 0);
 | ||
|     }
 | ||
|     XVT_IMAGE_FORMAT xif = bmp.GetDepth()>8 ? XVT_IMAGE_RGB : XVT_IMAGE_CL8;
 | ||
|     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();
 | ||
| #ifndef NDEBUG
 | ||
|  	if (!ok)
 | ||
|   {
 | ||
|     wxString msg;
 | ||
|     msg << "Can't find image code " << rid << " in resource.ini";
 | ||
|     xvt_dm_post_note(msg);
 | ||
|   }
 | ||
| #endif
 | ||
| 	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);
 | ||
|       if (max > 1)
 | ||
|         g.SetDeterminateMode();
 | ||
|       else
 | ||
|         g.SetIndeterminateMode();
 | ||
|     }
 | ||
|     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()
 | ||
| {
 | ||
| 	wxBeginBusyCursor();
 | ||
| }
 | ||
| 
 | ||
| void xvt_scr_reset_busy_cursor()
 | ||
| {
 | ||
| 	wxEndBusyCursor();
 | ||
| }
 | ||
| 
 | ||
| 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 s1 && s2 ? wxStricmp(s1, s2) : -883;
 | ||
| }
 | ||
| 
 | ||
| BOOLEAN xvt_str_same(const char* s1, const char* s2)
 | ||
| {
 | ||
| 	return s1 && s2 && wxStricmp(s1, s2) == 0;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 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);
 | ||
|   
 | ||
|   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
 | ||
|     if (!_task_win->IsIconized())
 | ||
|       _task_win->Raise();
 | ||
|   }
 | ||
|   else
 | ||
|   {
 | ||
|     // Qui iconizetask significa nascondi processo a task_win
 | ||
|     if (_task_win != NULL && _task_win_handler != NULL && !iconizetask) 
 | ||
|     {
 | ||
|       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);
 | ||
|     OsWin32_PlaceProcessInWindow(inst, "", (unsigned int)w.GetHandle());
 | ||
|   }
 | ||
|   return inst;
 | ||
| }
 | ||
| 
 | ||
| long xvt_sys_close_children(WINDOW win)
 | ||
| {
 | ||
|   CAST_WIN(win, w);
 | ||
|   return OsWin32_CloseChildren((unsigned int)w.GetHandle());
 | ||
| }
 | ||
| 
 | ||
| BOOLEAN xvt_sys_goto_url(const char* url, const char* action)
 | ||
| {
 | ||
|   if (action && *action && !xvt_str_same(action, "open"))  
 | ||
|     return OsWin32_GotoUrl(url, action);
 | ||
| 
 | ||
|   return wxLaunchDefaultBrowser(url);
 | ||
| }
 | ||
| 
 | ||
| int xvt_sys_dongle_server_running()
 | ||
| {
 | ||
|   int s = 0;
 | ||
|   if (OsWin32_ProcessModule("Authoriz.exe"))
 | ||
|     s |= 1;
 | ||
|   if (OsWin32_ProcessModule("SSAAgent.exe"))
 | ||
|     s |= 2;
 | ||
|   return s;
 | ||
| }
 | ||
| 
 | ||
| #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 && *paragraph) && wxStricmp(file, "ssa.ini") == 0)
 | ||
|   {
 | ||
|     if (xvt_fsys_file_exists(file))
 | ||
|     {
 | ||
|       wxTextFile ssa;
 | ||
|       ssa.Open(file);
 | ||
|       for (wxString str = ssa.GetFirstLine(); !ssa.Eof(); str = ssa.GetNextLine())
 | ||
|       {
 | ||
|         str.Trim(false);
 | ||
|         if (str.StartsWith(name))
 | ||
|         {
 | ||
|           str = str.AfterFirst('=');
 | ||
|           str.Trim(true); str.Trim(false);
 | ||
|           wxStrncpy(value, str, maxsize-1);
 | ||
|           return str.Len();
 | ||
|         }
 | ||
|       }
 | ||
|     }
 | ||
|     wxStrncpy(value, defval, maxsize-1);
 | ||
|     return wxStrlen(defval);
 | ||
|   }
 | ||
| 
 | ||
|   if (!(paragraph && *paragraph))
 | ||
|     paragraph = "Main";
 | ||
| 
 | ||
|   int len = ::GetPrivateProfileString(paragraph, name, defval, value, maxsize, file);
 | ||
|   return len;
 | ||
| }
 | ||
| 
 | ||
| long xvt_sys_get_profile_int(const char* file, const char* paragraph, const char* name, long defval)
 | ||
| {
 | ||
|   char defstr[16] = { 0 }, str[16] = { 0 };
 | ||
|   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_int(const char* file, const char* paragraph, const char* name, long value)
 | ||
| {
 | ||
|   char str[16] = { 0 }; wxSprintf(str, "%ld", value);
 | ||
|   return xvt_sys_set_profile_string(file, paragraph, name, str);
 | ||
| }
 | ||
| 
 | ||
| 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";
 | ||
| 
 | ||
|   return ::WritePrivateProfileString(paragraph, name, value, file) > 0;
 | ||
| }
 | ||
| 
 | ||
| BOOLEAN xvt_sys_find_editor(const char* file, char* editor)
 | ||
| {
 | ||
|   BOOLEAN ok = FALSE;
 | ||
| 
 | ||
|   const wxString e = OsWin32_File2App(file);
 | ||
|   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;
 | ||
| 
 | ||
|   int nVersion = 0;
 | ||
|   ::GetWinVer(NULL, 0, &nVersion);  // Implemented in XFont.cpp, not a Win32 API
 | ||
|   switch (nVersion)
 | ||
|   {
 | ||
|   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: os = XVT_WS_WIN_7;      break;
 | ||
|   case 110: os = XVT_WS_WIN_2012;   break;
 | ||
|   case 111: os = XVT_WS_WIN_8;      break;
 | ||
|   default : os = XVT_WS_WIN_10;      break;
 | ||
|   }
 | ||
| 
 | ||
|   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)
 | ||
|   {
 | ||
|     if (version >= XVT_WS_WIN_VISTA) 
 | ||
|       ::GetWinVer(os_version, maxsize, NULL);  // wxWidgets non sa descrivere i moderni sistemi Microsoft
 | ||
|     else
 | ||
|       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_search_env(const char * filename, const char * varname, char * pathname)
 | ||
| {
 | ||
|   _searchenv(filename, varname, pathname);
 | ||
| }
 | ||
| 
 | ||
| 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)
 | ||
| {
 | ||
| 	const wxURL url(pathname);
 | ||
| 	const wxString scheme = url.GetScheme();
 | ||
| 
 | ||
| 	if (scheme == "ftp" || scheme == "http")
 | ||
| 	{
 | ||
| 		if (mode & 4)
 | ||
| 			return ENOEXEC;
 | ||
| 		if (mode & 2 && scheme == "http")
 | ||
| 			return EACCES;
 | ||
| 
 | ||
| 	  if (scheme == "ftp")
 | ||
| 	  {
 | ||
|       const wxFileName fnPath = url.GetPath();
 | ||
| 		  const wxString fnDir = fnPath.GetPath(wxPATH_GET_VOLUME, wxPATH_UNIX);
 | ||
| 		  const wxString fnName = fnPath.GetFullName();
 | ||
|       if (fnName.IsEmpty()) // Test for directory existence
 | ||
|       {
 | ||
| 		    const wxString strHost = url.GetServer();
 | ||
|         const wxString strUser = url.GetUser();
 | ||
|         const wxString strPwd = url.GetPassword();
 | ||
|         wxFTP ftp;
 | ||
|         if (!strUser.IsEmpty())
 | ||
|         {
 | ||
|           ftp.SetUser(strUser);
 | ||
|           ftp.SetPassword(strPwd);
 | ||
|         }
 | ||
|         ftp.SetPassive(xvt_sys_ftp_passive_mode(strHost));
 | ||
|         return ftp.Connect(strHost) && ftp.ChDir(fnDir) ? 0 : EACCES;
 | ||
|       }
 | ||
|     }
 | ||
| 		SLIST files = xvt_fsys_list_files("", pathname, true);
 | ||
| 		const int count = xvt_slist_count(files);
 | ||
| 		
 | ||
| 		xvt_slist_destroy(files);
 | ||
| 		return count > 0 ? 0 : ENOENT;
 | ||
| 	}
 | ||
|   return wxAccess(pathname, mode) == -1 ? errno : 0;
 | ||
| }
 | ||
| 
 | ||
| BOOLEAN xvt_fsys_dir_exists(const char *pathname)
 | ||
| {
 | ||
|   return wxDirExists(pathname);
 | ||
| }
 | ||
| 
 | ||
| BOOLEAN xvt_fsys_file_exists(const char *pathname)
 | ||
| {
 | ||
|   return xvt_fsys_access(pathname, 0) == 0;
 | ||
| }
 | ||
| 
 | ||
| BOOLEAN xvt_fsys_mkdir(const char *pathname)
 | ||
| {
 | ||
|   // Crea l'intero albero di cartelle senza dare errori 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)
 | ||
| {
 | ||
| 	wxURL url(pathname);
 | ||
| 	wxString scheme = url.GetScheme();
 | ||
| 
 | ||
| 	if (scheme == "ftp")
 | ||
| 	{
 | ||
| 	  wxFTP ftp;
 | ||
|     const wxString strHost = url.GetServer();
 | ||
|     const wxString strUser = url.GetUser();
 | ||
|     const wxString strPwd = url.GetPassword();
 | ||
|     const wxFileName fnPath = url.GetPath();
 | ||
| 		const wxString  fnDir = fnPath.GetPath(wxPATH_GET_VOLUME, wxPATH_UNIX);
 | ||
| 		const wxString  fnName = fnPath.GetFullName();
 | ||
| 
 | ||
|     if (!strUser.IsEmpty())
 | ||
|     {
 | ||
|       ftp.SetUser(strUser);
 | ||
|       ftp.SetPassword(strPwd);
 | ||
|     }
 | ||
|     ftp.SetPassive(xvt_sys_ftp_passive_mode(strHost));
 | ||
| 
 | ||
|     if (ftp.Connect(strHost))
 | ||
| 				if (ftp.ChDir(fnDir))
 | ||
| 					return ftp.RmFile(fnName);
 | ||
| 		return false;
 | ||
| 	}
 | ||
| 	else
 | ||
| 		if (scheme == "http")
 | ||
| 			return false;
 | ||
| 	return wxRemoveFile(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
 | ||
|   } else
 | ||
|   if (win == PRINTER_WIN)
 | ||
|     GetTDCMapper().DestroyTDC(win);
 | ||
| }
 | ||
| 
 | ||
| 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_APPL_VERSION_YEAR:
 | ||
|     if (_appl_version.IsEmpty())
 | ||
|       ret = 2151;
 | ||
|     else
 | ||
|       ret = wxAtoi(_appl_version.Left(4));
 | ||
|     break;
 | ||
|   case ATTR_APPL_ALREADY_RUNNING:
 | ||
|     ret = _appl_already_running;
 | ||
|     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 = 0, h = 0;
 | ||
|   switch (win)
 | ||
|   {
 | ||
|   case NULL_WIN:
 | ||
|   	l = wxSystemSettings::GetMetric(wxSYS_SCREEN_X);
 | ||
| 	  h = wxSystemSettings::GetMetric(wxSYS_SCREEN_Y);
 | ||
|     break;
 | ||
|   case 882: // SCREEN_WIN
 | ||
|   	l = wxSystemSettings::GetMetric(wxSYS_SCREEN_X);
 | ||
| 	  h = wxSystemSettings::GetMetric(wxSYS_SCREEN_Y) - 32; // Puerile tentativo di escludere la task bar
 | ||
|     break;
 | ||
|   case PRINTER_WIN: 
 | ||
|     l = 4600; h = 6800; // circa A4 size at 600 DPI
 | ||
|     break; 
 | ||
|   default:
 | ||
|     {
 | ||
|   	  CAST_WIN(win, w);
 | ||
|       w.GetClientSize(&l, &h);
 | ||
|     }
 | ||
|     break;
 | ||
|   }
 | ||
|   xvt_rect_set(rctp, 0, 0, l, 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 || win == SCREEN_WIN)
 | ||
| 		return NULL_WIN;
 | ||
| 	CAST_WIN(win, w);
 | ||
| 	return (WINDOW)w.GetParent();
 | ||
| }
 | ||
| 
 | ||
| char* xvt_vobj_get_title(WINDOW win, char *title, int sz_title)
 | ||
| {
 | ||
|   if (win == NULL_WIN)
 | ||
|     return NULL;
 | ||
| 	CAST_WIN(win, w);
 | ||
| 	wxStrncpy(title, w.GetLabel(), sz_title);
 | ||
| 	title[sz_title-1] = '\0';
 | ||
| 	return title;
 | ||
| }
 | ||
| 
 | ||
| BOOLEAN xvt_vobj_is_focusable(WINDOW win)
 | ||
| {
 | ||
| 	BOOLEAN ok = win != NULL_WIN && win != PRINTER_WIN && 
 | ||
|                win != TASK_WIN && win != SCREEN_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_APPL_ALREADY_RUNNING: _appl_already_running = value != 0; 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
 | ||
| 
 | ||
|   OsWin32_SetCaptionStyle(w->GetHWND(), style);
 | ||
| 
 | ||
|   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)
 | ||
| {
 | ||
|   if (xvt_vobj_is_valid(win))  // Ignore setting cursor on invalid windows
 | ||
|   {
 | ||
| 	  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;
 | ||
| 
 | ||
|   
 | ||
| }
 | ||
| 
 | ||
| 
 |