diff --git a/xvaga/oswin32.cpp b/xvaga/oswin32.cpp index 1d9229582..55982d5a1 100755 --- a/xvaga/oswin32.cpp +++ b/xvaga/oswin32.cpp @@ -1,1071 +1,1105 @@ -#include "wxinc.h" -#include "wx/filename.h" -#include "wx/image.h" -#include "wx/paper.h" -#include "wx/printdlg.h" -#include "wx/msw/helpchm.h" - -#include "oswin32.h" -#include "aclapi.h" - -#include "xvt_menu.h" -#include "xvt_help.h" -#include "xvtart.h" - -#include "xvt_defs.h" -#include "xvt_env.h" -#include "xvt_type.h" -#include "xvtwin.h" - -bool OsWin32_CheckPrinterInfo(const void* data, unsigned int size) -{ - bool ok = data != NULL; - if (ok) - { - LPDEVMODE pdm = (LPDEVMODE)data; - const unsigned int s = pdm->dmSize + pdm->dmDriverExtra; - ok = s > 0 && s == size; - } - return ok; -} - -static int AdjustDevmodePlease(PDEVMODE dm) -{ - // Forse dovremmo fare una Black List su file delle stampanti incompatibili): - // 1) "NRG SP 4100N PCL 5e" - // 2) aggiungere qui le altre - // Ma per ora zappiamo tutti i driver troppo grandi (> 3Kb) - if (dm->dmDriverExtra > 3*1024) - dm->dmDriverExtra = 0; - - // Controllo il formato della carta - wxPrintPaperType* paper = wxThePrintPaperDatabase->FindPaperTypeByPlatformId(dm->dmPaperSize); - if (paper == NULL) - { - dm->dmFields |= DM_PAPERSIZE; - wxThePrintPaperDatabase->WXADDPAPER((wxPaperSize)dm->dmPaperSize /*wxPAPER_NONE*/, dm->dmPaperSize, - dm->dmFormName, dm->dmPaperWidth, dm->dmPaperLength); - } - - return dm->dmSize + dm->dmDriverExtra; -} - -void* OsWin32_ConvertFromNativePrinterInfo(void* hGlobal, unsigned int& nDataSize) -{ - void* buff = NULL; - if (hGlobal != NULL) - { - PDEVMODE dm = (PDEVMODE)::GlobalLock(hGlobal); - nDataSize = AdjustDevmodePlease(dm); - buff = new char[nDataSize]; - memcpy(buff, dm, nDataSize); - ::GlobalUnlock(hGlobal); - } - return buff; -} - -void* OsWin32_ConvertToNativePrinterInfo(void* data, unsigned int nDataSize) -{ - HGLOBAL hGlobal = ::GlobalAlloc(GHND, nDataSize); // Alloco lo spazio necessario - if (hGlobal != NULL) - { - PDEVMODE dm = (PDEVMODE)::GlobalLock(hGlobal); // Trasformo l'handle in puntatore - memcpy(dm, data, nDataSize); // Ricopio i dati della stampante - const unsigned int sz = AdjustDevmodePlease(dm); // Metto a posto parametri non standard - wxASSERT(nDataSize == sz); - ::GlobalUnlock(hGlobal); // Libero il lock sull'handle - } - return hGlobal; -} - -struct XvtData -{ - char** families; - long* sizes; - short* scalable; - int max_count; - int cur_count; - - XvtData() { memset(this, 0, sizeof(XvtData)); } -}; - -int CALLBACK FamilyEnumerator( - const LOGFONT *plf, // pointer to logical-font data - const TEXTMETRIC * WXUNUSED(lpntme), // pointer to physical-font data - unsigned long WXUNUSED(FontType), // type of font - LPARAM lParam // application-defined data -) -{ - XvtData* d = (XvtData*)lParam; - int& n = d->cur_count; - int i; - for (i = n-1; i >= 0 && wxStricmp(d->families[i], plf->lfFaceName); i--); - if (i < 0) // Controlla che il nome del font non ci sia gia' - d->families[n++] = wxStrdup(plf->lfFaceName); - return n < d->max_count; -} - -int CALLBACK SizeEnumerator( - const LOGFONT *plf, // pointer to logical-font data - const TEXTMETRIC *lpntme, // pointer to physical-font data - unsigned long WXUNUSED(FontType), // type of font - LPARAM lParam // application-defined data -) -{ - XvtData* d = (XvtData*)lParam; - int& i = d->cur_count; - int size = (plf->lfHeight+5) / 10; - if (size <= 0) - { - for (const char* n = plf->lfFaceName; *n; n++) - if (*n >= '1' && *n <= '9') - { - size = int(120.0 / atoi(n) + 0.5); - break; - } - if (size <= 0) - size = 12; - } - if (i == 0 || size > d->sizes[i-1]) - { - d->sizes[i] = size; - if (lpntme->tmPitchAndFamily & TMPF_TRUETYPE) - *d->scalable = TRUE; - i++; - } - return i < d->max_count; -} - -int FamilySorter(const void* p1,const void* p2) -{ - const char* s1 = *(const char**)p1; - const char* s2 = *(const char**)p2; - return wxStricmp(s1, s2); -} - -int OsWin32_EnumerateFamilies(WXHDC hDC, char** families, int max_count) -{ - XvtData data; - data.families = families; - data.max_count = max_count; - LOGFONT lf; memset(&lf, 0, sizeof(lf)); - lf.lfCharSet = DEFAULT_CHARSET; - ::EnumFontFamiliesEx((HDC)hDC, &lf, FamilyEnumerator, (LPARAM)&data, 0); - qsort(families, data.cur_count, sizeof(char*), FamilySorter); - return data.cur_count; -} - -int OsWin32_EnumerateSizes(WXHDC hDC, const char* name, long* sizes, short* scalable, int max_count) -{ - XvtData data; - data.sizes = sizes; - data.scalable = scalable; - data.max_count = max_count; - LOGFONT lf; memset(&lf, 0, sizeof(lf)); - lf.lfCharSet = DEFAULT_CHARSET; - strcpy(lf.lfFaceName, name); - ::EnumFontFamiliesEx((HDC)hDC, &lf, SizeEnumerator, (LPARAM)&data, 0); - - return data.cur_count; -} - -void* OsWin32_GetPrinterInfo(int& size, const char* printer) -{ - LPDEVMODE pdm = NULL; - size = 0; - - char name[_MAX_PATH] = ""; - if (printer == NULL || *printer == '\0') - { - unsigned long namelen = _MAX_PATH; - ::GetDefaultPrinter(name, &namelen); - } - else - wxStrncpy(name, printer, sizeof(name)); - - HANDLE hPrinter = NULL; - if (::OpenPrinter(name, &hPrinter, NULL)) - { - size = ::DocumentProperties(0, hPrinter, name, NULL, NULL, 0); // Determina dimensione DEVMODE - if (size > 0) - { - pdm = (LPDEVMODE)new BYTE[size]; // Alloca un DEVMODE sufficientemente capiente - memset(pdm, 0, size); // Azzera tutto per bene - ::DocumentProperties(0, hPrinter, name, pdm, NULL, DM_OUT_BUFFER); // Legge DEVMODE - size = AdjustDevmodePlease(pdm); - } - else - size = 0; - ::ClosePrinter(hPrinter); - } - return pdm; -} - -void OsWin32_SetCaptionStyle(WXHWND handle, long style) -{ - HWND hWnd = (HWND)handle; - LONG s = ::GetWindowLong(hWnd, GWL_STYLE); - - if (style & wxSYSTEM_MENU) - s |= WS_CAPTION; - else - s &= ~WS_CAPTION; - - if (style & wxCLOSE_BOX) - s |= WS_SYSMENU; - else - s &= ~WS_SYSMENU; - - s |= WS_CLIPSIBLINGS; // Forzatura necessaria da wx261 - ::SetWindowLong(hWnd, GWL_STYLE, s); - - if (style & wxCLOSE_BOX) - { - HMENU hMenu = ::GetSystemMenu(hWnd, FALSE); - ::EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | MF_ENABLED); - - WXHICON hIcon = xvtart_GetIconResource(0).GetHICON(); - ::SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon); - } -} - -/////////////////////////////////////////////////////////// -// Drawing bitmaps -/////////////////////////////////////////////////////////// - -HBITMAP OsWin32_CreateBitmap(const wxImage& img, wxDC& dc) -{ - static wxPalette pal; - - HDC hDC = (HDC)dc.GetHDC(); - int nDepth = dc.GetDepth(); - - // Altrimenti le stampanti in B/N perdono i toni di grigio - if (nDepth == 1 && !OsWin32_IsWindowsServer()) - { - hDC = NULL; - nDepth = 24; - } - - if (nDepth == 8) - { - if (!pal.Ok()) - { - unsigned char red[256], green[256], blue[256]; - PALETTEENTRY pe[256]; memset(pe, 0, sizeof(pe)); - UINT nEntries = ::GetSystemPaletteEntries(hDC, 0, 256, pe); - for (UINT i = 0; i < nEntries; i++) - { - red[i] = pe[i].peRed; - green[i] = pe[i].peGreen; - blue[i] = pe[i].peBlue; - } - pal.Create(nEntries, red, green, blue); - } - dc.SetPalette(pal); - } - - const int nWidth = img.GetWidth(); - const int nHeight = img.GetHeight(); - - int nBytesPerLine = 0; - int nPadding = 0; - int nBitCount = 24; - - switch (nDepth) - { - case 32: // Better if > Win98 :-) too - nBitCount = 32; - nBytesPerLine = nWidth*4; - break; - default: - nBytesPerLine = nWidth*3; - break; - } - const int nResto = nBytesPerLine % 4; - if (nResto != 0) - { - nPadding = 4 - nResto; - nBytesPerLine += nPadding; - } - - const int nImageSize = nHeight*nBytesPerLine; - - // Create the DIB section - unsigned char* pbits = (unsigned char*)calloc(nImageSize, 1); - const size_t bi_size = sizeof(BITMAPINFOHEADER); - BITMAPINFO* bi = (BITMAPINFO*)calloc(bi_size, 1); - bi->bmiHeader.biSize = bi_size; - bi->bmiHeader.biWidth = nWidth; - bi->bmiHeader.biHeight = -nHeight; - bi->bmiHeader.biCompression = BI_RGB; - bi->bmiHeader.biPlanes = 1; - bi->bmiHeader.biBitCount = nBitCount; - bi->bmiHeader.biSizeImage = nImageSize; - - switch (nBitCount) - { - case 24: - { - unsigned char* d = img.GetData(); - unsigned char* p = pbits; - for (int y = 0; y < nHeight; y++) - { - for (int x = 0; x < nWidth; x++) - { - *(p++) = *(d+2); - *(p++) = *(d+1); - *(p++) = *(d+0); - d += 3; - } - for (int i = 0; i < nPadding; i++) - *(p++) = 0; - } - } - break; - case 32: - { - unsigned char* d = img.GetData(); - unsigned char* p = pbits; - for (int y = 0; y < nHeight; y++) - { - for (int x = 0; x < nWidth; x++) - { - *(p++) = *(d+2); - *(p++) = *(d+1); - *(p++) = *(d+0); - *(p++) = 0; - d += 3; - } - } - } - break; - default: - break; - } - - HBITMAP hBitmap = ::CreateCompatibleBitmap(hDC, nWidth, nHeight); - if (hBitmap) - { - HDC memdc = ::CreateCompatibleDC( hDC ); - HBITMAP hOldBitmap = (HBITMAP)::SelectObject( memdc, hBitmap); - - HPALETTE hOldPalette = NULL; - if (nDepth == 8) - { - hOldPalette = ::SelectPalette(memdc, (HPALETTE)pal.GetHPALETTE(), FALSE); - ::RealizePalette(memdc); - } - ::StretchDIBits( memdc, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight, pbits, bi, DIB_RGB_COLORS, SRCCOPY); - - if (hOldBitmap) - ::SelectObject(memdc, hOldBitmap); - if (hOldPalette) - ::SelectPalette(memdc, hOldPalette, FALSE); - ::DeleteDC(memdc); - - } - - free(pbits); - free(bi); - - return hBitmap; -} - -bool OsWin32_DrawBitmap(HBITMAP hBMP, wxDC& dc, const wxRect& dst, const wxRect& src) -{ - static wxPalette pal; - - bool ok = hBMP != NULL; - - if (ok) - { - HDC hDC = (HDC)dc.GetHDC(); - const int nTechno = ::GetDeviceCaps(hDC, TECHNOLOGY); - - HDC hMemDC = NULL; - if (OsWin32_IsWindowsServer()) - hMemDC = ::CreateCompatibleDC(hDC); // Per Terminal Server devo fare cosi' - else - hMemDC = ::CreateCompatibleDC(NULL); // Per gli altri sistemi devo fare cosa' - - BITMAP bmp; ::GetObject(hBMP, sizeof(bmp), &bmp); - - if (nTechno == DT_RASPRINTER) // Sto stampando! - { - const size_t bi_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD); - BITMAPINFO* bi = (BITMAPINFO*)calloc(bi_size, 1); // Alloca ed azzera - BITMAPINFOHEADER& bih = bi->bmiHeader; - bih.biSize = sizeof(bih); - GetDIBits(hMemDC, hBMP, 0, bmp.bmHeight, NULL, bi, DIB_RGB_COLORS); - ok = bih.biSizeImage > 0; - if (ok) - { - LPBYTE bits = new BYTE[bih.biSizeImage]; - ::GetDIBits(hMemDC, hBMP, 0, src.height, bits, bi, DIB_RGB_COLORS); - ::StretchDIBits(hDC, dst.x, dst.y, dst.width, dst.height, src.x, src.y, src.width, src.height, - bits, bi, DIB_RGB_COLORS, SRCCOPY); - delete bits; - } - free(bi); - } - else - { - HGDIOBJ hOldBitmap = ::SelectObject(hMemDC, hBMP); - ::SetStretchBltMode(hDC, HALFTONE); - ::StretchBlt(hDC, dst.x, dst.y, dst.width, dst.height, - hMemDC, src.x, src.y, src.width, src.height, SRCCOPY); - ::SelectObject(hMemDC, hOldBitmap); - } - - ::DeleteDC(hMemDC); - } - return ok; -} - -void OsWin32_DrawDottedRect(WXHDC hDC, int left, int top, int right, int bottom) -{ - LOGBRUSH lBrush; - lBrush.lbHatch = 0; lBrush.lbStyle = BS_SOLID; - lBrush.lbColor = ::GetTextColor((HDC)hDC); - HPEN hPen = ::ExtCreatePen(PS_COSMETIC|PS_ALTERNATE, 1, &lBrush, 0, NULL); - HGDIOBJ hOldPen = ::SelectObject((HDC)hDC, hPen); - HGDIOBJ hBrush = ::GetStockObject(HOLLOW_BRUSH); - HGDIOBJ hOldBrush = ::SelectObject((HDC)hDC, hBrush); - ::Rectangle((HDC)hDC, left, top, right, bottom); - ::SelectObject((HDC)hDC, hOldBrush); - ::SelectObject((HDC)hDC, hOldPen); - ::DeleteObject(hPen); -} - -void OsWin32_Beep(int severity) -{ - switch (severity) - { - case 1: ::MessageBeep(MB_ICONEXCLAMATION); break; - case 2: ::MessageBeep(MB_ICONSTOP); break; - default: ::MessageBeep(MB_OK); break; - } -} - -static wxString GetHelpDir() -{ return "htmlhelp/"; } - -static wxString FindHelpFile(const char* topic) -{ - wxString strTopic = topic; - - wxString strApp; - wxFileName::SplitPath(wxTheApp->argv[0], NULL, &strApp, NULL); - - if (strTopic.IsEmpty()) - { - strTopic = strApp; - strTopic += "100a"; - } - - wxString str; - for (int i = 0; i < 2; i++) - { - str = GetHelpDir(); - str += i == 0 ? strTopic.Left(2) : strApp.Left(2); - str += "help.pdf"; - if (::wxFileExists(str)) - return str; - } - - for (int i = 0; i < 2; i++) - { - str = GetHelpDir(); - str += i == 0 ? strTopic.Left(2) : strApp.Left(2); - str += "help.chm"; - if (::wxFileExists(str)) - return str; - } - for (int i = 0; i < 2; i++) - { - str = GetHelpDir(); - str += i == 0 ? strTopic.Left(2) : strApp.Left(2); - str += "/"; - str += strTopic; - str += ".html"; - if (::wxFileExists(str)) - return str; - } - - return wxEmptyString; -} - -int OsWin32_Help(WXHWND handle, const char* hlp, unsigned int cmd, const char* topic) -{ - wxString str = hlp; - if (str.IsEmpty() || !wxFileExists(str)) - { - switch(cmd) - { - case M_HELP_ONCONTEXT: - str = FindHelpFile(topic); - if (wxFileExists(str)) - break; - default: - str = FindHelpFile(topic); - if (wxFileExists(str)) - { - topic = NULL; - } - else - { - str = GetHelpDir(); - str += "index.html"; - } - break; - } - } - if (!str.IsEmpty() && wxFileExists(str)) - { - if (str.EndsWith(".pdf")) - { - wxString strCmd = OsWin32_File2App(str); - if (topic && *topic) - strCmd << " /A nameddest=" << topic; - strCmd << " " << str; - ::wxExecute(strCmd); - } else - if (str.EndsWith(".chm")) - { - static wxCHMHelpController* hlp = new wxCHMHelpController; - if (hlp->LoadFile(str)) - { - wxString strSection = topic; - strSection += ".html"; - hlp->DisplaySection(strSection); - } - } else - if (str.EndsWith(".html")) - { - wxFileName fn = str; - fn.MakeAbsolute(); - str = fn.GetFullPath(); - ::ShellExecute((HWND)handle, "open", str, NULL, NULL, SW_SHOWNORMAL); - } - - return true; - } - OsWin32_Beep(1); // Error beep - return false; -} - -/////////////////////////////////////////////////////////// -// Execute in window support -/////////////////////////////////////////////////////////// - -struct TFindWindowInfo -{ - HINSTANCE _instance; - wxString _file; - HWND _hwnd; - - TFindWindowInfo() : _instance(NULL), _hwnd(NULL) { } -}; - -static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) -{ - TFindWindowInfo* w = (TFindWindowInfo*)lParam; - - if (w->_instance != NULL) - { - HINSTANCE inst = (HINSTANCE)::GetWindowLong(hwnd, GWL_HINSTANCE); - if (inst == w->_instance) - { - // Cerco di capire se e' la finetra principale dal fatto che - // abbia la caption ed i bottoni di chiusura - const DWORD dwWanted = WS_CAPTION | WS_SYSMENU; - const DWORD style = ::GetWindowLong(hwnd, GWL_STYLE); - if ((style & dwWanted) == dwWanted) - { - w->_hwnd = hwnd; - return FALSE; - } - return TRUE; - } - } - - if (!w->_file.IsEmpty()) - { - char str[_MAX_PATH]; - if (::GetWindowText(hwnd, str, sizeof(str))) - { - wxString title = str; - title.MakeUpper(); - if (title.Find(w->_file) >= 0) - { - w->_hwnd = hwnd; - return FALSE; - } - } - } - - return TRUE; -} - -void OsWin32_PlaceProcessInWindow(unsigned int instance, const char* name, unsigned int parent) -{ - TFindWindowInfo w; - w._instance = (HINSTANCE)instance; - w._file = name; - w._file.MakeUpper(); - - for (int i = 0; w._hwnd == NULL && i < 20; i++) - { - ::wxMilliSleep(500); - ::EnumWindows(EnumWindowsProc, LPARAM(&w)); - } - - if (w._hwnd != NULL) // L'ho trovata! - { - RECT rct; ::GetClientRect((HWND)parent, &rct); - ::SetParent(w._hwnd, (HWND)parent); - const int fx = ::GetSystemMetrics(SM_CXFRAME); - const int fy = ::GetSystemMetrics(SM_CYFRAME); - int cy = ::GetSystemMetrics(SM_CYCAPTION)+GetSystemMetrics(SM_CYBORDER); - if (::GetMenu(w._hwnd) != NULL) - cy += ::GetSystemMetrics(SM_CYMENU); - ::SetWindowPos(w._hwnd, (HWND)parent, -fx, -fy-cy, rct.right+2*fx, rct.bottom+cy+2*fy, SWP_NOZORDER); - } -} - -static BOOL CALLBACK EnumCampoChildrenProc(HWND hwnd, LPARAM lParam) -{ - char str[_MAX_PATH]; - if (::GetWindowText(hwnd, str, sizeof(str))) - { - TFindWindowInfo* w = (TFindWindowInfo*)lParam; - if (w->_file == str) // str == "__CAMPO_HOST_WINDOW__" - { - str[13] = '\0'; // Impedisce che questa finestra abbia altri figli indesiderati - ::SetWindowText(hwnd, str); - w->_hwnd = hwnd; - return FALSE; // Fine della ricerca - } - } - return TRUE; // Continua a cercare -} - -static BOOL CALLBACK EnumCampoMenuChildrenProc(HWND hwnd, LPARAM lParam) -{ - char str[_MAX_PATH]; - if (::GetWindowText(hwnd, str, sizeof(str))) - { - const wxString title = str; - if (title.StartsWith("Base - ")) // Scandisco solo i figli del menu - { - ::EnumChildWindows(hwnd, EnumCampoChildrenProc, lParam); - const TFindWindowInfo* w = (TFindWindowInfo*)lParam; - if (w->_hwnd != NULL) - return FALSE; // Fine della ricerca - } - } - return TRUE; // Continua a cercare -} - -unsigned int OsWin32_FindMenuContainer() -{ - TFindWindowInfo w; - w._file = "__CAMPO_HOST_WINDOW__"; - ::EnumWindows(EnumCampoMenuChildrenProc, LPARAM(&w)); - return (unsigned int)w._hwnd; -} - -static BOOL CALLBACK CountChildrenProc(HWND WXUNUSED(hwnd), LPARAM lParam) -{ - if (lParam) - { - LONG* n = (LONG*)lParam; - (*n)++; - } - return TRUE; -} - -long OsWin32_GetChildrenCount(unsigned int parent) -{ - LONG n = 0; - ::EnumChildWindows((HWND)parent, CountChildrenProc, (LPARAM)&n); - return n; -} - -static BOOL CALLBACK CloseChildrenProc(HWND hwnd, LPARAM lParam) -{ - ::PostMessage(hwnd, WM_CLOSE, 0, 0); - return CountChildrenProc(hwnd, lParam); -} - -long OsWin32_CloseChildren(unsigned int parent) -{ - LONG n = 0; - ::EnumChildWindows((HWND)parent, CloseChildrenProc, (LPARAM)&n); - return n; -} - -/////////////////////////////////////////////////////////// -// Hardlock Support -/////////////////////////////////////////////////////////// - -#include "hlapi_c.h" - -bool OsWin32_HL_Login(unsigned short address, const unsigned char* label, const unsigned char* password) -{ - int err = HL_LOGIN(address, LOCAL_DEVICE, (unsigned char*)label, (unsigned char*)password); - return err == STATUS_OK; -} - -bool OsWin32_HL_Logout() -{ - HL_LOGOUT(); - return TRUE; -} - -bool OsWin32_HL_Read(unsigned short reg, unsigned short* data) -{ - int err = HL_READ(reg, data); - return err == STATUS_OK; -} - -bool OsWin32_HL_ReadBlock(unsigned char* data) -{ - int err = HL_READBL(data); - return err == STATUS_OK; -} - -bool OsWin32_HL_Write(unsigned short reg, unsigned short data) -{ - int err = HL_WRITE(reg, data); - return err == STATUS_OK; -} - -bool OsWin32_HL_Crypt(unsigned short* data) // Array di 4 words (8 bytes) -{ - int err = HL_CODE(data, 1); - return err == STATUS_OK; -} - -/////////////////////////////////////////////////////////// -// Eutron Smartlink Support -/////////////////////////////////////////////////////////// - -#include "skeylink.h" - -static KEY_NET _eutron_key; - -bool OsWin32_SL_Crypt(unsigned short* data) -{ - _eutron_key.net_command = NET_KEY_ACCESS; - _eutron_key.command = SCRAMBLING_MODE; - memcpy(_eutron_key.data, data, 8); - smartlink(&_eutron_key); - if (_eutron_key.status == ST_OK) - memcpy(data, _eutron_key.data, 8); - return _eutron_key.status == ST_OK; -} - -bool OsWin32_SL_Login(const unsigned char* label, const unsigned char* password) -{ - memset(&_eutron_key, 0, sizeof(KEY_NET)); - _eutron_key.net_command = NET_KEY_OPEN; - _eutron_key.status = ST_HW_FAILURE; // Don't leave ST_OK = 0 here! - memcpy(_eutron_key.label, label, strlen((const char*)label)); - memcpy(_eutron_key.password, password, strlen((const char*)password)); - - smartlink(&_eutron_key); - return _eutron_key.status == ST_OK; -} - -bool OsWin32_SL_Logout() -{ - _eutron_key.net_command = NET_KEY_CLOSE; - _eutron_key.command = 0; - smartlink(&_eutron_key); - return true; -} - -bool OsWin32_SL_ReadBlock(unsigned short reg, unsigned short size, unsigned short* data) -{ - _eutron_key.net_command = NET_KEY_ACCESS; - _eutron_key.command = BLOCK_READING_MODE; - unsigned short* pointer = (unsigned short*)(&_eutron_key.data[0]); - unsigned short* number = (unsigned short*)(&_eutron_key.data[2]); - *pointer = reg; - *number = size; - smartlink(&_eutron_key); - bool ok = _eutron_key.status == ST_OK; - if (ok) - memcpy(data, &_eutron_key.data[4], size*sizeof(unsigned short)); - return ok; -} - -bool OsWin32_SL_WriteBlock(unsigned short reg, unsigned short size, const unsigned short* data) -{ - _eutron_key.net_command = NET_KEY_ACCESS; - _eutron_key.command = BLOCK_WRITING_MODE; - unsigned short* pointer = (unsigned short*)(&_eutron_key.data[0]); - unsigned short* number = (unsigned short*)(&_eutron_key.data[2]); - *pointer = reg; - *number = size; - memcpy(&_eutron_key.data[4], data, size*sizeof(unsigned short)); - smartlink(&_eutron_key); - return _eutron_key.status == ST_OK; -} - -/////////////////////////////////////////////////////////// -// Ex-Golem utilities -/////////////////////////////////////////////////////////// - -static long GetRegistryString(HKEY key, const char* subkey, wxString& retstr) -{ - HKEY hkey; - long retval = ::RegOpenKey(key, subkey, &hkey); - if (retval == ERROR_SUCCESS) - { - char retdata[_MAX_PATH]; - long datasize = sizeof(retdata); - ::RegQueryValue(hkey, NULL, retdata, &datasize); - ::RegCloseKey(hkey); - retstr = retdata; - } - return retval; -} - -wxString OsWin32_File2App(const char* filename) -{ - wxString app; - - if (*filename != '.') - { - char retdata[_MAX_PATH]; - HINSTANCE hinst = ::FindExecutable(filename, ".", retdata); - DWORD* pinst = (DWORD*)hinst; - UINT err = LOWORD(pinst); - if (err > 32) - app = retdata; - } - - if (app.IsEmpty()) - { - wxString ext; - if (*filename == '.') - ext = filename; - else - { - wxSplitPath(filename, NULL, NULL, &ext); - if (!ext.StartsWith(".")) - ext = "." + ext; - } - ext.MakeLower(); - - wxString key; - if (GetRegistryString(HKEY_CLASSES_ROOT, ext, key) == ERROR_SUCCESS) - { - key << "\\shell\\open\\command"; - if (GetRegistryString(HKEY_CLASSES_ROOT, key, key) == ERROR_SUCCESS) - { - key.Replace("\"", " "); - int pos = key.Find("%1"); - if (pos > 0) - key.Truncate(pos); - key.Trim(false); key.Trim(true); - app = key; - } - } - } - - return app; -} - -static bool IsInternetAddress(const char* filename) -{ - wxString url(filename); url.MakeLower(); - if (url.StartsWith("http:") || url.StartsWith("ftp:")) - return true; - if (url.Find("www.") >= 0) - return true; - - wxString ext; wxFileName::SplitPath(url, NULL, NULL, NULL, &ext); - const char* const extensions[] = { "com","edu","eu","gov","it","mil","net","org", NULL }; - for (int e = 0; extensions[e]; e++) - if (ext == extensions[e]) - return true; - - return false; -} - -wxIcon OsWin32_LoadIcon(const char* filename) -{ - int icon_number = 0; - - wxString ext; - if (*filename == '.' && strlen(filename) < _MAX_EXT) - ext = filename; - else - { - if (IsInternetAddress(filename)) - ext = ".htm"; - else - { - wxFileName::SplitPath(filename, NULL, NULL, NULL, &ext); - if (!ext.StartsWith(".")) - ext.insert(0, "."); - } - } - ext.MakeLower(); - - wxString key; - if (ext != ".exe") - { - if (::GetRegistryString(HKEY_CLASSES_ROOT, ext, key) == ERROR_SUCCESS) - { - key << "\\DefaultIcon"; - if (::GetRegistryString(HKEY_CLASSES_ROOT, key, key) == ERROR_SUCCESS) // Windows 95 only - { - const int comma = key.find(','); - if (comma > 0) - { - icon_number = atoi(key.Mid(comma+1)); - key.Truncate(comma); - } - } - else - { - key = OsWin32_File2App(filename); - if (key.IsEmpty()) - key = OsWin32_File2App(".htm"); - } - } - } - else - key = filename; - - // Toglie eventuali parametri sulla riga si comando - const int ext_pos = key.Find(".exe"); - if (ext_pos > 0) - key.Truncate(ext_pos+4); - - wxString strFullName = key; - if (icon_number > 0) - strFullName << ";" << icon_number; - - wxIcon ico(strFullName, wxBITMAP_TYPE_ICO); - return ico; -} - -// action = [ open, edit, print ]; -bool OsWin32_GotoUrl(const char* url, const char* action) -{ - bool ok = false; - - // Sarebbe meglio un flag esplicito, ma per ora attendiamo solo le stampe - if (action && wxStricmp(action, "print") == 0) - { - SHELLEXECUTEINFO sei; memset(&sei, 0, sizeof(sei)); - sei.cbSize = sizeof(sei); - sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT; - sei.lpVerb = action; - sei.lpFile = url; - sei.nShow = SW_SHOWNORMAL; - if (::ShellExecuteEx(&sei)) - { - if (sei.hProcess != NULL) - { - ::WaitForSingleObject(sei.hProcess, 0); - ::CloseHandle(sei.hProcess); - } - ok = true; - } - } - else - { - HINSTANCE hinst = ::ShellExecute(NULL, action, url, NULL, NULL, SW_SHOWNORMAL); - DWORD winst = DWORD((DWORD*)hinst); // Tutto 'sto giro per evitare un warning - ok = UINT(winst) > 32; - } - return ok; -} - -#ifdef SPEECH_API - -#include - -static ISpVoice* m_pVoice = NULL; - -bool OsWin32_InitializeSpeech() -{ - if (m_pVoice == NULL) - CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&m_pVoice); - return m_pVoice != NULL; -} - -void OsWin32_DeinitializeSpeech() -{ - if (m_pVoice != NULL) - { - m_pVoice->WaitUntilDone(1000); - m_pVoice->Release(); - m_pVoice = NULL; - } -} - -bool OsWin32_Speak(const char* text, bool async) -{ - if (m_pVoice != NULL) - { - WCHAR str[1204]; - MultiByteToWideChar(CP_ACP, 0, text, -1, str, strlen(text)+1); - if (async) - m_pVoice->Speak(str, SPF_ASYNC | SPF_PURGEBEFORESPEAK, NULL); - else - m_pVoice->Speak(str, SPF_PURGEBEFORESPEAK, NULL); - return true; - } - return false; -} - -#endif - -int OsWin32_GetSessionId() -{ - DWORD session = 0; - ::ProcessIdToSessionId(::GetCurrentProcessId(), &session); - return (int)session; -} - -bool OsWin32_IsWindowsServer() -{ - return ::GetSystemMetrics(SM_REMOTESESSION) != 0; -} - -void OsWin32_NumberFormat(char* str, int size) -{ - static char decsep = '\0', thosep = '\0'; - - char buf[80] = ""; - if (!decsep) - { - ::GetNumberFormat(LOCALE_USER_DEFAULT, 0, "1936.27", NULL, buf, sizeof(buf)); - decsep = buf[strlen(buf)-3]; - thosep = buf[1] == '9' ? '\0' : buf[1]; - } - - if (str && *str) - { - int j = 0; - for (int i = 0; str[i]; i++) - { - switch (str[i]) - { - case '.': buf[j++] = decsep; break; - case ',': break; // Ignore thousand separator - default : buf[j++] = str[i]; break; - } - } - buf[j] = '\0'; - wxStrncpy(str, buf, size); - } -} +#include "wxinc.h" +#include "wx/filename.h" +#include "wx/image.h" +#include "wx/paper.h" +#include "wx/printdlg.h" +#include "wx/msw/helpchm.h" + +#include "oswin32.h" +#include "aclapi.h" + +#include "xvt_menu.h" +#include "xvt_help.h" +#include "xvtart.h" + +#include "xvt_defs.h" +#include "xvt_env.h" +#include "xvt_type.h" +#include "xvtwin.h" + +bool OsWin32_CheckPrinterInfo(const void* data, unsigned int size) +{ + bool ok = data != NULL; + if (ok) + { + LPDEVMODE pdm = (LPDEVMODE)data; + const unsigned int s = pdm->dmSize + pdm->dmDriverExtra; + ok = s > 0 && s == size; + } + return ok; +} + +static int AdjustDevmodePlease(PDEVMODE dm) +{ + // Forse dovremmo fare una Black List su file delle stampanti incompatibili): + // 1) "NRG SP 4100N PCL 5e" + // 2) aggiungere qui le altre + // Ma per ora zappiamo tutti i driver troppo grandi (> 3Kb) + if (dm->dmDriverExtra > 3*1024) + dm->dmDriverExtra = 0; + + // Controllo il formato della carta + wxPrintPaperType* paper = wxThePrintPaperDatabase->FindPaperTypeByPlatformId(dm->dmPaperSize); + if (paper == NULL) + { + dm->dmFields |= DM_PAPERSIZE; + wxThePrintPaperDatabase->WXADDPAPER((wxPaperSize)dm->dmPaperSize /*wxPAPER_NONE*/, dm->dmPaperSize, + dm->dmFormName, dm->dmPaperWidth, dm->dmPaperLength); + } + + return dm->dmSize + dm->dmDriverExtra; +} + +void* OsWin32_ConvertFromNativePrinterInfo(void* hGlobal, unsigned int& nDataSize) +{ + void* buff = NULL; + if (hGlobal != NULL) + { + PDEVMODE dm = (PDEVMODE)::GlobalLock(hGlobal); + nDataSize = AdjustDevmodePlease(dm); + buff = new char[nDataSize]; + memcpy(buff, dm, nDataSize); + ::GlobalUnlock(hGlobal); + } + return buff; +} + +void* OsWin32_ConvertToNativePrinterInfo(void* data, unsigned int nDataSize) +{ + HGLOBAL hGlobal = ::GlobalAlloc(GHND, nDataSize); // Alloco lo spazio necessario + if (hGlobal != NULL) + { + PDEVMODE dm = (PDEVMODE)::GlobalLock(hGlobal); // Trasformo l'handle in puntatore + memcpy(dm, data, nDataSize); // Ricopio i dati della stampante + const unsigned int sz = AdjustDevmodePlease(dm); // Metto a posto parametri non standard + wxASSERT(nDataSize == sz); + ::GlobalUnlock(hGlobal); // Libero il lock sull'handle + } + return hGlobal; +} + +struct XvtData +{ + char** families; + long* sizes; + short* scalable; + int max_count; + int cur_count; + + XvtData() { memset(this, 0, sizeof(XvtData)); } +}; + +int CALLBACK FamilyEnumerator( + const LOGFONT *plf, // pointer to logical-font data + const TEXTMETRIC * WXUNUSED(lpntme), // pointer to physical-font data + unsigned long WXUNUSED(FontType), // type of font + LPARAM lParam // application-defined data +) +{ + XvtData* d = (XvtData*)lParam; + int& n = d->cur_count; + int i; + for (i = n-1; i >= 0 && wxStricmp(d->families[i], plf->lfFaceName); i--); + if (i < 0) // Controlla che il nome del font non ci sia gia' + d->families[n++] = wxStrdup(plf->lfFaceName); + return n < d->max_count; +} + +int CALLBACK SizeEnumerator( + const LOGFONT *plf, // pointer to logical-font data + const TEXTMETRIC *lpntme, // pointer to physical-font data + unsigned long WXUNUSED(FontType), // type of font + LPARAM lParam // application-defined data +) +{ + XvtData* d = (XvtData*)lParam; + int& i = d->cur_count; + int size = (plf->lfHeight+5) / 10; + if (size <= 0) + { + for (const char* n = plf->lfFaceName; *n; n++) + if (*n >= '1' && *n <= '9') + { + size = int(120.0 / atoi(n) + 0.5); + break; + } + if (size <= 0) + size = 12; + } + if (i == 0 || size > d->sizes[i-1]) + { + d->sizes[i] = size; + if (lpntme->tmPitchAndFamily & TMPF_TRUETYPE) + *d->scalable = TRUE; + i++; + } + return i < d->max_count; +} + +int FamilySorter(const void* p1,const void* p2) +{ + const char* s1 = *(const char**)p1; + const char* s2 = *(const char**)p2; + return wxStricmp(s1, s2); +} + +int OsWin32_EnumerateFamilies(WXHDC hDC, char** families, int max_count) +{ + XvtData data; + data.families = families; + data.max_count = max_count; + LOGFONT lf; memset(&lf, 0, sizeof(lf)); + lf.lfCharSet = DEFAULT_CHARSET; + ::EnumFontFamiliesEx((HDC)hDC, &lf, FamilyEnumerator, (LPARAM)&data, 0); + qsort(families, data.cur_count, sizeof(char*), FamilySorter); + return data.cur_count; +} + +int OsWin32_EnumerateSizes(WXHDC hDC, const char* name, long* sizes, short* scalable, int max_count) +{ + XvtData data; + data.sizes = sizes; + data.scalable = scalable; + data.max_count = max_count; + LOGFONT lf; memset(&lf, 0, sizeof(lf)); + lf.lfCharSet = DEFAULT_CHARSET; + strcpy(lf.lfFaceName, name); + ::EnumFontFamiliesEx((HDC)hDC, &lf, SizeEnumerator, (LPARAM)&data, 0); + + return data.cur_count; +} + +void* OsWin32_GetPrinterInfo(int& size, const char* printer) +{ + LPDEVMODE pdm = NULL; + size = 0; + + char name[_MAX_PATH] = ""; + if (printer == NULL || *printer == '\0') + { + unsigned long namelen = _MAX_PATH; + ::GetDefaultPrinter(name, &namelen); + } + else + wxStrncpy(name, printer, sizeof(name)); + + HANDLE hPrinter = NULL; + if (::OpenPrinter(name, &hPrinter, NULL)) + { + size = ::DocumentProperties(0, hPrinter, name, NULL, NULL, 0); // Determina dimensione DEVMODE + if (size > 0) + { + pdm = (LPDEVMODE)new BYTE[size]; // Alloca un DEVMODE sufficientemente capiente + memset(pdm, 0, size); // Azzera tutto per bene + ::DocumentProperties(0, hPrinter, name, pdm, NULL, DM_OUT_BUFFER); // Legge DEVMODE + size = AdjustDevmodePlease(pdm); + } + else + size = 0; + ::ClosePrinter(hPrinter); + } + return pdm; +} + +void OsWin32_SetCaptionStyle(WXHWND handle, long style) +{ + HWND hWnd = (HWND)handle; + LONG s = ::GetWindowLong(hWnd, GWL_STYLE); + + if (style & wxSYSTEM_MENU) + s |= WS_CAPTION; + else + s &= ~WS_CAPTION; + + if (style & wxCLOSE_BOX) + s |= WS_SYSMENU; + else + s &= ~WS_SYSMENU; + + s |= WS_CLIPSIBLINGS; // Forzatura necessaria da wx261 + ::SetWindowLong(hWnd, GWL_STYLE, s); + + if (style & wxCLOSE_BOX) + { + HMENU hMenu = ::GetSystemMenu(hWnd, FALSE); + ::EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | MF_ENABLED); + + WXHICON hIcon = xvtart_GetIconResource(0).GetHICON(); + ::SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon); + } +} + +/////////////////////////////////////////////////////////// +// Drawing bitmaps +/////////////////////////////////////////////////////////// + +HBITMAP OsWin32_CreateBitmap(const wxImage& img, wxDC& dc) +{ + static wxPalette pal; + + HDC hDC = (HDC)dc.GetHDC(); + int nDepth = dc.GetDepth(); + + // Altrimenti le stampanti in B/N perdono i toni di grigio + if (nDepth == 1 && !OsWin32_IsWindowsServer()) + { + hDC = NULL; + nDepth = 24; + } + + if (nDepth == 8) + { + if (!pal.Ok()) + { + unsigned char red[256], green[256], blue[256]; + PALETTEENTRY pe[256]; memset(pe, 0, sizeof(pe)); + UINT nEntries = ::GetSystemPaletteEntries(hDC, 0, 256, pe); + for (UINT i = 0; i < nEntries; i++) + { + red[i] = pe[i].peRed; + green[i] = pe[i].peGreen; + blue[i] = pe[i].peBlue; + } + pal.Create(nEntries, red, green, blue); + } + dc.SetPalette(pal); + } + + const int nWidth = img.GetWidth(); + const int nHeight = img.GetHeight(); + + int nBytesPerLine = 0; + int nPadding = 0; + int nBitCount = 24; + + switch (nDepth) + { + case 32: // Better if > Win98 :-) too + nBitCount = 32; + nBytesPerLine = nWidth*4; + break; + default: + nBytesPerLine = nWidth*3; + break; + } + const int nResto = nBytesPerLine % 4; + if (nResto != 0) + { + nPadding = 4 - nResto; + nBytesPerLine += nPadding; + } + + const int nImageSize = nHeight*nBytesPerLine; + + // Create the DIB section + unsigned char* pbits = (unsigned char*)calloc(nImageSize, 1); + const size_t bi_size = sizeof(BITMAPINFOHEADER); + BITMAPINFO* bi = (BITMAPINFO*)calloc(bi_size, 1); + bi->bmiHeader.biSize = bi_size; + bi->bmiHeader.biWidth = nWidth; + bi->bmiHeader.biHeight = -nHeight; + bi->bmiHeader.biCompression = BI_RGB; + bi->bmiHeader.biPlanes = 1; + bi->bmiHeader.biBitCount = nBitCount; + bi->bmiHeader.biSizeImage = nImageSize; + + switch (nBitCount) + { + case 24: + { + unsigned char* d = img.GetData(); + unsigned char* p = pbits; + for (int y = 0; y < nHeight; y++) + { + for (int x = 0; x < nWidth; x++) + { + *(p++) = *(d+2); + *(p++) = *(d+1); + *(p++) = *(d+0); + d += 3; + } + for (int i = 0; i < nPadding; i++) + *(p++) = 0; + } + } + break; + case 32: + { + unsigned char* d = img.GetData(); + unsigned char* p = pbits; + for (int y = 0; y < nHeight; y++) + { + for (int x = 0; x < nWidth; x++) + { + *(p++) = *(d+2); + *(p++) = *(d+1); + *(p++) = *(d+0); + *(p++) = 0; + d += 3; + } + } + } + break; + default: + break; + } + + HBITMAP hBitmap = ::CreateCompatibleBitmap(hDC, nWidth, nHeight); + if (hBitmap) + { + HDC memdc = ::CreateCompatibleDC( hDC ); + HBITMAP hOldBitmap = (HBITMAP)::SelectObject( memdc, hBitmap); + + HPALETTE hOldPalette = NULL; + if (nDepth == 8) + { + hOldPalette = ::SelectPalette(memdc, (HPALETTE)pal.GetHPALETTE(), FALSE); + ::RealizePalette(memdc); + } + ::StretchDIBits( memdc, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight, pbits, bi, DIB_RGB_COLORS, SRCCOPY); + + if (hOldBitmap) + ::SelectObject(memdc, hOldBitmap); + if (hOldPalette) + ::SelectPalette(memdc, hOldPalette, FALSE); + ::DeleteDC(memdc); + + } + + free(pbits); + free(bi); + + return hBitmap; +} + +bool OsWin32_DrawBitmap(HBITMAP hBMP, wxDC& dc, const wxRect& dst, const wxRect& src) +{ + static wxPalette pal; + + bool ok = hBMP != NULL; + + if (ok) + { + HDC hDC = (HDC)dc.GetHDC(); + const int nTechno = ::GetDeviceCaps(hDC, TECHNOLOGY); + + HDC hMemDC = NULL; + if (OsWin32_IsWindowsServer()) + hMemDC = ::CreateCompatibleDC(hDC); // Per Terminal Server devo fare cosi' + else + hMemDC = ::CreateCompatibleDC(NULL); // Per gli altri sistemi devo fare cosa' + + BITMAP bmp; ::GetObject(hBMP, sizeof(bmp), &bmp); + + if (nTechno == DT_RASPRINTER) // Sto stampando! + { + const size_t bi_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD); + BITMAPINFO* bi = (BITMAPINFO*)calloc(bi_size, 1); // Alloca ed azzera + BITMAPINFOHEADER& bih = bi->bmiHeader; + bih.biSize = sizeof(bih); + GetDIBits(hMemDC, hBMP, 0, bmp.bmHeight, NULL, bi, DIB_RGB_COLORS); + ok = bih.biSizeImage > 0; + if (ok) + { + LPBYTE bits = new BYTE[bih.biSizeImage]; + ::GetDIBits(hMemDC, hBMP, 0, src.height, bits, bi, DIB_RGB_COLORS); + ::StretchDIBits(hDC, dst.x, dst.y, dst.width, dst.height, src.x, src.y, src.width, src.height, + bits, bi, DIB_RGB_COLORS, SRCCOPY); + delete bits; + } + free(bi); + } + else + { + HGDIOBJ hOldBitmap = ::SelectObject(hMemDC, hBMP); + ::SetStretchBltMode(hDC, HALFTONE); + ::StretchBlt(hDC, dst.x, dst.y, dst.width, dst.height, + hMemDC, src.x, src.y, src.width, src.height, SRCCOPY); + ::SelectObject(hMemDC, hOldBitmap); + } + + ::DeleteDC(hMemDC); + } + return ok; +} + +void OsWin32_DrawDottedRect(WXHDC hDC, int left, int top, int right, int bottom) +{ + LOGBRUSH lBrush; + lBrush.lbHatch = 0; lBrush.lbStyle = BS_SOLID; + lBrush.lbColor = ::GetTextColor((HDC)hDC); + HPEN hPen = ::ExtCreatePen(PS_COSMETIC|PS_ALTERNATE, 1, &lBrush, 0, NULL); + HGDIOBJ hOldPen = ::SelectObject((HDC)hDC, hPen); + HGDIOBJ hBrush = ::GetStockObject(HOLLOW_BRUSH); + HGDIOBJ hOldBrush = ::SelectObject((HDC)hDC, hBrush); + ::Rectangle((HDC)hDC, left, top, right, bottom); + ::SelectObject((HDC)hDC, hOldBrush); + ::SelectObject((HDC)hDC, hOldPen); + ::DeleteObject(hPen); +} + +void OsWin32_Beep(int severity) +{ + switch (severity) + { + case 1: ::MessageBeep(MB_ICONEXCLAMATION); break; + case 2: ::MessageBeep(MB_ICONSTOP); break; + default: ::MessageBeep(MB_OK); break; + } +} + +static wxString GetHelpDir() +{ return "htmlhelp/"; } + +static wxString FindHelpFile(const char* topic) +{ + wxString strTopic = topic; + + wxString strApp; + wxFileName::SplitPath(wxTheApp->argv[0], NULL, &strApp, NULL); + + if (strTopic.IsEmpty()) + { + strTopic = strApp; + strTopic += "100a"; + } + + wxString str; + for (int i = 0; i < 2; i++) + { + str = GetHelpDir(); + str += i == 0 ? strTopic.Left(2) : strApp.Left(2); + str += "help.pdf"; + if (::wxFileExists(str)) + return str; + } + + for (int i = 0; i < 2; i++) + { + str = GetHelpDir(); + str += i == 0 ? strTopic.Left(2) : strApp.Left(2); + str += "help.chm"; + if (::wxFileExists(str)) + return str; + } + for (int i = 0; i < 2; i++) + { + str = GetHelpDir(); + str += i == 0 ? strTopic.Left(2) : strApp.Left(2); + str += "/"; + str += strTopic; + str += ".html"; + if (::wxFileExists(str)) + return str; + } + + return wxEmptyString; +} + +int OsWin32_Help(WXHWND handle, const char* hlp, unsigned int cmd, const char* topic) +{ + wxString str = hlp; + if (str.IsEmpty() || !wxFileExists(str)) + { + switch(cmd) + { + case M_HELP_ONCONTEXT: + str = FindHelpFile(topic); + if (wxFileExists(str)) + break; + default: + str = FindHelpFile(topic); + if (wxFileExists(str)) + { + topic = NULL; + } + else + { + str = GetHelpDir(); + str += "index.html"; + } + break; + } + } + if (!str.IsEmpty() && wxFileExists(str)) + { + if (str.EndsWith(".pdf")) + { + wxString strCmd = OsWin32_File2App(str); + if (topic && *topic) + strCmd << " /A nameddest=" << topic; + strCmd << " " << str; + ::wxExecute(strCmd); + } else + if (str.EndsWith(".chm")) + { + static wxCHMHelpController* hlp = new wxCHMHelpController; + if (hlp->LoadFile(str)) + { + wxString strSection = topic; + strSection += ".html"; + hlp->DisplaySection(strSection); + } + } else + if (str.EndsWith(".html")) + { + wxFileName fn = str; + fn.MakeAbsolute(); + str = fn.GetFullPath(); + ::ShellExecute((HWND)handle, "open", str, NULL, NULL, SW_SHOWNORMAL); + } + + return true; + } + OsWin32_Beep(1); // Error beep + return false; +} + +/////////////////////////////////////////////////////////// +// Execute in window support +/////////////////////////////////////////////////////////// + +struct TFindWindowInfo +{ + HINSTANCE _instance; + wxString _file; + HWND _hwnd; + + TFindWindowInfo() : _instance(NULL), _hwnd(NULL) { } +}; + +static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) +{ + TFindWindowInfo* w = (TFindWindowInfo*)lParam; + + if (w->_instance != NULL) + { + HINSTANCE inst = (HINSTANCE)::GetWindowLong(hwnd, GWL_HINSTANCE); + if (inst == w->_instance) + { + // Cerco di capire se e' la finetra principale dal fatto che + // abbia la caption ed i bottoni di chiusura + const DWORD dwWanted = WS_CAPTION | WS_SYSMENU; + const DWORD style = ::GetWindowLong(hwnd, GWL_STYLE); + if ((style & dwWanted) == dwWanted) + { + w->_hwnd = hwnd; + return FALSE; + } + return TRUE; + } + } + + if (!w->_file.IsEmpty()) + { + char str[_MAX_PATH]; + if (::GetWindowText(hwnd, str, sizeof(str))) + { + wxString title = str; + title.MakeUpper(); + if (title.Find(w->_file) >= 0) + { + w->_hwnd = hwnd; + return FALSE; + } + } + } + + return TRUE; +} + +void OsWin32_PlaceProcessInWindow(unsigned int instance, const char* name, unsigned int parent) +{ + TFindWindowInfo w; + w._instance = (HINSTANCE)instance; + w._file = name; + w._file.MakeUpper(); + + for (int i = 0; w._hwnd == NULL && i < 20; i++) + { + ::wxMilliSleep(500); + ::EnumWindows(EnumWindowsProc, LPARAM(&w)); + } + + if (w._hwnd != NULL) // L'ho trovata! + { + RECT rct; ::GetClientRect((HWND)parent, &rct); + ::SetParent(w._hwnd, (HWND)parent); + const int fx = ::GetSystemMetrics(SM_CXFRAME); + const int fy = ::GetSystemMetrics(SM_CYFRAME); + int cy = ::GetSystemMetrics(SM_CYCAPTION)+GetSystemMetrics(SM_CYBORDER); + if (::GetMenu(w._hwnd) != NULL) + cy += ::GetSystemMetrics(SM_CYMENU); + ::SetWindowPos(w._hwnd, (HWND)parent, -fx, -fy-cy, rct.right+2*fx, rct.bottom+cy+2*fy, SWP_NOZORDER); + } +} + +static BOOL CALLBACK EnumCampoChildrenProc(HWND hwnd, LPARAM lParam) +{ + char str[_MAX_PATH]; + if (::GetWindowText(hwnd, str, sizeof(str))) + { + TFindWindowInfo* w = (TFindWindowInfo*)lParam; + if (w->_file == str) // str == "__CAMPO_HOST_WINDOW__" + { + str[13] = '\0'; // Impedisce che questa finestra abbia altri figli indesiderati + ::SetWindowText(hwnd, str); + w->_hwnd = hwnd; + return FALSE; // Fine della ricerca + } + } + return TRUE; // Continua a cercare +} + +static BOOL CALLBACK EnumCampoMenuChildrenProc(HWND hwnd, LPARAM lParam) +{ + char str[_MAX_PATH]; + if (::GetWindowText(hwnd, str, sizeof(str))) + { + const wxString title = str; + if (title.StartsWith("Base - ")) // Scandisco solo i figli del menu + { + ::EnumChildWindows(hwnd, EnumCampoChildrenProc, lParam); + const TFindWindowInfo* w = (TFindWindowInfo*)lParam; + if (w->_hwnd != NULL) + return FALSE; // Fine della ricerca + } + } + return TRUE; // Continua a cercare +} + +#include +#include + +unsigned int OsWin32_FindMenuContainer() +{ + wxString strApp; + wxFileName::SplitPath(wxTheApp->argv[0], NULL, &strApp, NULL); + strApp.MakeLower(); + if (strApp == "ba0" || strApp == "ba1" || strApp == "ba7") + return 0; // Special programs that can't be hosted by ba0 + + const DWORD pid = ::GetCurrentProcessId(); + HANDLE h = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + PROCESSENTRY32 pe = { 0 }; pe.dwSize = sizeof(PROCESSENTRY32); + + DWORD ppid = 0; + for(BOOL ok = ::Process32First(h, &pe); ok; ok = ::Process32Next(h, &pe)) + { + if (pe.th32ProcessID == pid) + { + ppid = pe.th32ParentProcessID; + break; + } + } + ::CloseHandle(h); + + char strParentPath[_MAX_PATH] = ""; + HMODULE m = (HMODULE)::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ppid); + ::GetModuleFileNameEx(m, 0, strParentPath, sizeof(strParentPath) - 1); + ::CloseHandle(m); + + wxFileName::SplitPath(strParentPath, NULL, &strApp, NULL); + strApp.MakeLower(); + if (strApp != "ba0") + return 0; // Parent process is not ba0 + + TFindWindowInfo w; + w._file = "__CAMPO_HOST_WINDOW__"; + ::EnumWindows(EnumCampoMenuChildrenProc, LPARAM(&w)); + return (unsigned int)w._hwnd; +} + +static BOOL CALLBACK CountChildrenProc(HWND WXUNUSED(hwnd), LPARAM lParam) +{ + if (lParam) + { + LONG* n = (LONG*)lParam; + (*n)++; + } + return TRUE; +} + +long OsWin32_GetChildrenCount(unsigned int parent) +{ + LONG n = 0; + ::EnumChildWindows((HWND)parent, CountChildrenProc, (LPARAM)&n); + return n; +} + +static BOOL CALLBACK CloseChildrenProc(HWND hwnd, LPARAM lParam) +{ + ::PostMessage(hwnd, WM_CLOSE, 0, 0); + return CountChildrenProc(hwnd, lParam); +} + +long OsWin32_CloseChildren(unsigned int parent) +{ + LONG n = 0; + ::EnumChildWindows((HWND)parent, CloseChildrenProc, (LPARAM)&n); + return n; +} + +/////////////////////////////////////////////////////////// +// Hardlock Support +/////////////////////////////////////////////////////////// + +#include "hlapi_c.h" + +bool OsWin32_HL_Login(unsigned short address, const unsigned char* label, const unsigned char* password) +{ + int err = HL_LOGIN(address, LOCAL_DEVICE, (unsigned char*)label, (unsigned char*)password); + return err == STATUS_OK; +} + +bool OsWin32_HL_Logout() +{ + HL_LOGOUT(); + return TRUE; +} + +bool OsWin32_HL_Read(unsigned short reg, unsigned short* data) +{ + int err = HL_READ(reg, data); + return err == STATUS_OK; +} + +bool OsWin32_HL_ReadBlock(unsigned char* data) +{ + int err = HL_READBL(data); + return err == STATUS_OK; +} + +bool OsWin32_HL_Write(unsigned short reg, unsigned short data) +{ + int err = HL_WRITE(reg, data); + return err == STATUS_OK; +} + +bool OsWin32_HL_Crypt(unsigned short* data) // Array di 4 words (8 bytes) +{ + int err = HL_CODE(data, 1); + return err == STATUS_OK; +} + +/////////////////////////////////////////////////////////// +// Eutron Smartlink Support +/////////////////////////////////////////////////////////// + +#include "skeylink.h" + +static KEY_NET _eutron_key; + +bool OsWin32_SL_Crypt(unsigned short* data) +{ + _eutron_key.net_command = NET_KEY_ACCESS; + _eutron_key.command = SCRAMBLING_MODE; + memcpy(_eutron_key.data, data, 8); + smartlink(&_eutron_key); + if (_eutron_key.status == ST_OK) + memcpy(data, _eutron_key.data, 8); + return _eutron_key.status == ST_OK; +} + +bool OsWin32_SL_Login(const unsigned char* label, const unsigned char* password) +{ + memset(&_eutron_key, 0, sizeof(KEY_NET)); + _eutron_key.net_command = NET_KEY_OPEN; + _eutron_key.status = ST_HW_FAILURE; // Don't leave ST_OK = 0 here! + memcpy(_eutron_key.label, label, strlen((const char*)label)); + memcpy(_eutron_key.password, password, strlen((const char*)password)); + + smartlink(&_eutron_key); + return _eutron_key.status == ST_OK; +} + +bool OsWin32_SL_Logout() +{ + _eutron_key.net_command = NET_KEY_CLOSE; + _eutron_key.command = 0; + smartlink(&_eutron_key); + return true; +} + +bool OsWin32_SL_ReadBlock(unsigned short reg, unsigned short size, unsigned short* data) +{ + _eutron_key.net_command = NET_KEY_ACCESS; + _eutron_key.command = BLOCK_READING_MODE; + unsigned short* pointer = (unsigned short*)(&_eutron_key.data[0]); + unsigned short* number = (unsigned short*)(&_eutron_key.data[2]); + *pointer = reg; + *number = size; + smartlink(&_eutron_key); + bool ok = _eutron_key.status == ST_OK; + if (ok) + memcpy(data, &_eutron_key.data[4], size*sizeof(unsigned short)); + return ok; +} + +bool OsWin32_SL_WriteBlock(unsigned short reg, unsigned short size, const unsigned short* data) +{ + _eutron_key.net_command = NET_KEY_ACCESS; + _eutron_key.command = BLOCK_WRITING_MODE; + unsigned short* pointer = (unsigned short*)(&_eutron_key.data[0]); + unsigned short* number = (unsigned short*)(&_eutron_key.data[2]); + *pointer = reg; + *number = size; + memcpy(&_eutron_key.data[4], data, size*sizeof(unsigned short)); + smartlink(&_eutron_key); + return _eutron_key.status == ST_OK; +} + +/////////////////////////////////////////////////////////// +// Ex-Golem utilities +/////////////////////////////////////////////////////////// + +static long GetRegistryString(HKEY key, const char* subkey, wxString& retstr) +{ + HKEY hkey; + long retval = ::RegOpenKey(key, subkey, &hkey); + if (retval == ERROR_SUCCESS) + { + char retdata[_MAX_PATH]; + long datasize = sizeof(retdata); + ::RegQueryValue(hkey, NULL, retdata, &datasize); + ::RegCloseKey(hkey); + retstr = retdata; + } + return retval; +} + +wxString OsWin32_File2App(const char* filename) +{ + wxString app; + + if (*filename != '.') + { + char retdata[_MAX_PATH]; + HINSTANCE hinst = ::FindExecutable(filename, ".", retdata); + DWORD* pinst = (DWORD*)hinst; + UINT err = LOWORD(pinst); + if (err > 32) + app = retdata; + } + + if (app.IsEmpty()) + { + wxString ext; + if (*filename == '.') + ext = filename; + else + { + wxSplitPath(filename, NULL, NULL, &ext); + if (!ext.StartsWith(".")) + ext = "." + ext; + } + ext.MakeLower(); + + wxString key; + if (GetRegistryString(HKEY_CLASSES_ROOT, ext, key) == ERROR_SUCCESS) + { + key << "\\shell\\open\\command"; + if (GetRegistryString(HKEY_CLASSES_ROOT, key, key) == ERROR_SUCCESS) + { + key.Replace("\"", " "); + int pos = key.Find("%1"); + if (pos > 0) + key.Truncate(pos); + key.Trim(false); key.Trim(true); + app = key; + } + } + } + + return app; +} + +static bool IsInternetAddress(const char* filename) +{ + wxString url(filename); url.MakeLower(); + if (url.StartsWith("http:") || url.StartsWith("ftp:")) + return true; + if (url.Find("www.") >= 0) + return true; + + wxString ext; wxFileName::SplitPath(url, NULL, NULL, NULL, &ext); + const char* const extensions[] = { "com","edu","eu","gov","it","mil","net","org", NULL }; + for (int e = 0; extensions[e]; e++) + if (ext == extensions[e]) + return true; + + return false; +} + +wxIcon OsWin32_LoadIcon(const char* filename) +{ + int icon_number = 0; + + wxString ext; + if (*filename == '.' && strlen(filename) < _MAX_EXT) + ext = filename; + else + { + if (IsInternetAddress(filename)) + ext = ".htm"; + else + { + wxFileName::SplitPath(filename, NULL, NULL, NULL, &ext); + if (!ext.StartsWith(".")) + ext.insert(0, "."); + } + } + ext.MakeLower(); + + wxString key; + if (ext != ".exe") + { + if (::GetRegistryString(HKEY_CLASSES_ROOT, ext, key) == ERROR_SUCCESS) + { + key << "\\DefaultIcon"; + if (::GetRegistryString(HKEY_CLASSES_ROOT, key, key) == ERROR_SUCCESS) // Windows 95 only + { + const int comma = key.find(','); + if (comma > 0) + { + icon_number = atoi(key.Mid(comma+1)); + key.Truncate(comma); + } + } + else + { + key = OsWin32_File2App(filename); + if (key.IsEmpty()) + key = OsWin32_File2App(".htm"); + } + } + } + else + key = filename; + + // Toglie eventuali parametri sulla riga si comando + const int ext_pos = key.Find(".exe"); + if (ext_pos > 0) + key.Truncate(ext_pos+4); + + wxString strFullName = key; + if (icon_number > 0) + strFullName << ";" << icon_number; + + wxIcon ico(strFullName, wxBITMAP_TYPE_ICO); + return ico; +} + +// action = [ open, edit, print ]; +bool OsWin32_GotoUrl(const char* url, const char* action) +{ + bool ok = false; + + // Sarebbe meglio un flag esplicito, ma per ora attendiamo solo le stampe + if (action && wxStricmp(action, "print") == 0) + { + SHELLEXECUTEINFO sei; memset(&sei, 0, sizeof(sei)); + sei.cbSize = sizeof(sei); + sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT; + sei.lpVerb = action; + sei.lpFile = url; + sei.nShow = SW_SHOWNORMAL; + if (::ShellExecuteEx(&sei)) + { + if (sei.hProcess != NULL) + { + ::WaitForSingleObject(sei.hProcess, 0); + ::CloseHandle(sei.hProcess); + } + ok = true; + } + } + else + { + HINSTANCE hinst = ::ShellExecute(NULL, action, url, NULL, NULL, SW_SHOWNORMAL); + DWORD winst = DWORD((DWORD*)hinst); // Tutto 'sto giro per evitare un warning + ok = UINT(winst) > 32; + } + return ok; +} + +#ifdef SPEECH_API + +#include + +static ISpVoice* m_pVoice = NULL; + +bool OsWin32_InitializeSpeech() +{ + if (m_pVoice == NULL) + CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&m_pVoice); + return m_pVoice != NULL; +} + +void OsWin32_DeinitializeSpeech() +{ + if (m_pVoice != NULL) + { + m_pVoice->WaitUntilDone(1000); + m_pVoice->Release(); + m_pVoice = NULL; + } +} + +bool OsWin32_Speak(const char* text, bool async) +{ + if (m_pVoice != NULL) + { + WCHAR str[1204]; + MultiByteToWideChar(CP_ACP, 0, text, -1, str, strlen(text)+1); + if (async) + m_pVoice->Speak(str, SPF_ASYNC | SPF_PURGEBEFORESPEAK, NULL); + else + m_pVoice->Speak(str, SPF_PURGEBEFORESPEAK, NULL); + return true; + } + return false; +} + +#endif + +int OsWin32_GetSessionId() +{ + DWORD session = 0; + ::ProcessIdToSessionId(::GetCurrentProcessId(), &session); + return (int)session; +} + +bool OsWin32_IsWindowsServer() +{ + return ::GetSystemMetrics(SM_REMOTESESSION) != 0; +} + +void OsWin32_NumberFormat(char* str, int size) +{ + static char decsep = '\0', thosep = '\0'; + + char buf[80] = ""; + if (!decsep) + { + ::GetNumberFormat(LOCALE_USER_DEFAULT, 0, "1936.27", NULL, buf, sizeof(buf)); + decsep = buf[strlen(buf)-3]; + thosep = buf[1] == '9' ? '\0' : buf[1]; + } + + if (str && *str) + { + int j = 0; + for (int i = 0; str[i]; i++) + { + switch (str[i]) + { + case '.': buf[j++] = decsep; break; + case ',': break; // Ignore thousand separator + default : buf[j++] = str[i]; break; + } + } + buf[j] = '\0'; + wxStrncpy(str, buf, size); + } +} diff --git a/xvaga/xvt_ssa.cpp b/xvaga/xvt_ssa.cpp index 7a950fca9..ef3261b86 100644 --- a/xvaga/xvt_ssa.cpp +++ b/xvaga/xvt_ssa.cpp @@ -25,6 +25,27 @@ static const char* xvt_dongle_sa_id() return id; } +static const char* xvt_dongle_sa_product() +{ + static const char* product = NULL; + if (product == NULL) + { + const char* const products[] = { "CAMPO", "Campo", "campo", NULL }; + for (int i = 0; products[i]; i++) + { + if (SSA_Login(xvt_dongle_sa_id(), products[i]) == 0) + { + product = products[i]; + break; + } + } + if (product == NULL) + product = products[0]; + } + return product; +} + + static BOOLEAN xvt_dongle_sa_is_remote_ba0() { BOOLEAN yes = FALSE; @@ -76,11 +97,10 @@ int xvt_dongle_sa_login(const char* module) { if (_ssa_serial < 0) { - err = SSA_Login(xvt_dongle_sa_id(), "Campo"); + err = SSA_Login(xvt_dongle_sa_id(), xvt_dongle_sa_product()); if (err == 0) { - err = _ssa_serial = SSA_NumeroSerie("Campo"); - + err = _ssa_serial = SSA_NumeroSerie(xvt_dongle_sa_product()); if (_ssa_timer == NULL && xvt_dongle_sa_is_remote_ba0()) _ssa_timer = new TSSA_Pinger; } @@ -131,7 +151,7 @@ int xvt_dongle_sa_logout(const char* module) } else { - err = SSA_Logout(xvt_dongle_sa_id(), "Campo"); + err = SSA_Logout(xvt_dongle_sa_id(), xvt_dongle_sa_product()); if (err == 0) { _ssa_serial = SSA_UTENTE_NON_LOGGATO; diff --git a/xvaga/xvtart.cpp b/xvaga/xvtart.cpp index 6ebd4ffa5..39186eca2 100755 --- a/xvaga/xvtart.cpp +++ b/xvaga/xvtart.cpp @@ -1,393 +1,393 @@ -#include "wxinc.h" - -#include "xvt.h" -#include "xvtart.h" -#include "oswin32.h" - -#include -#include -#include - -wxString xvtart_GetResourceIni() -{ - DIRECTORY dir; xvt_fsys_get_default_dir(&dir); - wxString str = dir.path; - str += "/res/resource.ini"; - return str; -} - -wxString xvtart_GetResourceName(const char* type, int rid) -{ - wxString strName(type); strName << "s"; - wxString strKey; strKey.Printf("%d", rid); - - DIRECTORY dir; xvt_fsys_get_default_dir(&dir); - wxString startup_dir = dir.path; - - if ((rid == ICON_RSRC || rid == 0) && strName == "Icons") - { - int i = 1; - switch (xvt_sys_get_os_version()) - { - case XVT_WS_WIN_2000: - case XVT_WS_WIN_2003: i = 0; break; // Cerco prima l'icona a 256 colori - default : i = 1; break; // Cerco solo l'icona in RGBA - } - for (; i < 2; i++) - { - const char* const oem_var = i == 0 ? "Icon256" : "Icon"; - char name[MAX_PATH]; - if (xvt_sys_get_oem_string(oem_var, "", name, sizeof(name))) - { - wxFileName fname(startup_dir + "/setup/" + name); - if (fname.FileExists()) - { - fname.Normalize(); - strName = fname.GetFullPath().Lower(); - return strName; - } - } - } - } - - wxString val; - char* buff = val.GetWriteBuf(MAX_PATH); - xvt_sys_get_profile_string(xvtart_GetResourceIni(), strName, strKey, "", buff, MAX_PATH); - val.UngetWriteBuf(); - - if (!val.IsEmpty()) - { - strName = startup_dir; - strName += "/custom/"; - strName += val; - - if (!wxFileExists(strName)) - { - strName = startup_dir; - strName += "/res/"; - strName += val; - } - - wxFileName fname(strName); - fname.Normalize(); - strName = fname.GetFullPath().Lower(); - } - else - strName.Empty(); - - return strName; -} - -/////////////////////////////////////////////////////////// -// TArtProvider -/////////////////////////////////////////////////////////// - -class TArtProvider : public wxArtProvider -{ -#if !wxCHECK_VERSION(2,9,0) - WX_DECLARE_STRING_HASH_MAP(wxIconBundle, TIconBundleHashTable); - TIconBundleHashTable m_hmBundles; - - WX_DECLARE_STRING_HASH_MAP(unsigned, TIconIdHashTable); - TIconIdHashTable m_hmIds; -#endif - -protected: - virtual wxBitmap CreateBitmap(const wxArtID& id, const wxArtClient& client, const wxSize& size); - virtual wxIconBundle CreateIconBundle(const wxArtID& id, const wxArtClient& client); - -public: -#if !wxCHECK_VERSION(2,9,0) - wxIconBundle GetIconBundle(const wxArtID& id, const wxArtClient& client); - wxIcon GetIcon(const wxArtID& id, const wxArtClient& client = wxART_OTHER, const wxSize& size = wxDefaultSize); - wxSize GetNativeSizeHint(const wxArtClient& client); -#endif - unsigned int GetIconBundleNumber(const wxArtID& id); -}; - -TArtProvider* _TheArtProvider = NULL; - -void xvtart_Init() -{ - if (_TheArtProvider == NULL) - _TheArtProvider = new TArtProvider; - wxArtProvider::Push(_TheArtProvider); -} - -wxBitmap TArtProvider::CreateBitmap(const wxArtID& id, const wxArtClient& client, const wxSize& size) -{ - wxString strName; - - long tool = -1; - if (id.StartsWith(wxT("wxART"))) - { - if (id == wxART_ERROR) tool = 201; else - if (id == wxART_HELP) tool = 163; else - if (id == wxART_INFORMATION) tool = 162; else - if (id == wxART_MISSING_IMAGE) tool = 100; else - if (id == wxART_NEW) tool = 105; else - if (id == wxART_QUESTION) tool = 202; else - if (id == wxART_QUIT) tool = 114; else - if (id == wxART_WARNING) tool = 203; else - ; - } - else - id.ToLong(&tool); - - if (tool > 0) - { - strName = xvtart_GetResourceName("Tool", tool); - if (strName.IsEmpty() || !::wxFileExists(strName)) - strName = xvtart_GetResourceName("Tool", 100); // Default empty icon - } - else - strName = id; - - if (!strName.IsEmpty() && ::wxFileExists(strName)) - { - if (strName.EndsWith(".ico")) - { - const wxIcon ico = GetIcon(strName, client, size); - return wxBitmap(ico); - } - else - { - int sx = size.x, sy = size.y; - if (sx <= 0 || sy <= 0) - { - const wxSize sz = GetNativeSizeHint(client); - if (sx <= 0) sx = sz.x; - if (sy <= 0) sy = sz.y; - } - wxImage img(strName, wxBITMAP_TYPE_ANY); - img.Rescale(sx, sy, wxIMAGE_QUALITY_HIGH); - return wxBitmap(img); - } - } - - return wxNullBitmap; -} - -wxIconBundle TArtProvider::CreateIconBundle(const wxArtID& id, const wxArtClient& WXUNUSED(client)) -{ - wxString strName = id; - - long nIco = -1; - if (id.StartsWith(wxT("wxART"))) - { - if (id == wxART_EXECUTABLE_FILE) nIco = ICON_RSRC; else - ; - } - else - id.ToLong(&nIco); - - if (nIco > 0) - strName = xvtart_GetResourceName("Icon", nIco); - - wxIconBundle ib; - bool bFound = false; - if (::wxFileExists(strName)) - { - const bool bLog = wxLog::EnableLogging(false); // Evita segnalazione di errore di formato icona - if (strName.EndsWith(wxT(".ico"))) - { - ib.AddIcon(strName, wxBITMAP_TYPE_ICO); - bFound = true; - } - else - { - ib.AddIcon(OsWin32_LoadIcon(strName)); - bFound = true; - } - wxLog::EnableLogging(bLog); - - for (wxCoord s = 16; s <= 48; s += 16) - { - const wxIcon smico = ib.GetIcon(s); - if (smico.GetWidth() != s) - { - wxBitmap bmpbig(ib.GetIcon()); - wxImage img = bmpbig.ConvertToImage(); - img.Rescale(s, s, wxIMAGE_QUALITY_HIGH); - wxBitmap bmpsmall(img); - wxIcon icosmall; icosmall.CopyFromBitmap(bmpsmall); - ib.AddIcon(icosmall); - } - } - } - else - { - if (!strName.IsEmpty()) // Getione caso strName=".ext" - { - ib.AddIcon(OsWin32_LoadIcon(strName)); - bFound = true; - } - } - - if (!bFound && nIco == ICON_RSRC) - { - strName.Printf("%d", ICON_RSRC); // id puo' essere wxART_EXECUTABLE_FILE - ib.AddIcon(wxIcon(strName, wxBITMAP_TYPE_ICO_RESOURCE)); - } - - return ib; -} - -#if !wxCHECK_VERSION(2,9,0) - -wxSize TArtProvider::GetNativeSizeHint(const wxArtClient& client) -{ - int ix = 32, iy = 32; - - if (client == wxART_FRAME_ICON) - { - const int x = wxSystemSettings::GetMetric(wxSYS_SMALLICON_X); - const int y = wxSystemSettings::GetMetric(wxSYS_SMALLICON_Y); - if (x > 0 && y > 0) - { ix = x; iy = y; } - else - { ix /= 2; iy /= 2; } - } - else - { - const int x = wxSystemSettings::GetMetric(wxSYS_ICON_X); - const int y = wxSystemSettings::GetMetric(wxSYS_ICON_Y); - if (x > 0 && y > 0) - { ix = x; iy = y; } - if (client == wxART_MESSAGE_BOX) - { ix *= 2; iy *= 2; } - } - - return wxSize(ix,iy); -} - -wxIconBundle TArtProvider::GetIconBundle(const wxArtID& id, const wxArtClient& client) -{ - TIconBundleHashTable::iterator it = m_hmBundles.find(id); - if (it == m_hmBundles.end()) - { - const wxIconBundle b = CreateIconBundle(id, client); - m_hmBundles[id] = b; - - unsigned long uid = 0; - if (!id.ToULong(&uid)) - { - wxString numid; numid.Printf(wxT("%lu"), GetIconBundleNumber(id)); - m_hmBundles[numid] = b; - } - - return b; - } - return it->second; -} - -wxIcon TArtProvider::GetIcon(const wxArtID& id, const wxArtClient& client, const wxSize& size) -{ - wxIconBundle bundle = GetIconBundle(id, client); - const wxSize sz = size == wxDefaultSize ? GetNativeSizeHint(client) : size; - wxIcon ico = bundle.GetIcon(sz); - if (ico.IsOk() && sz.x != ico.GetWidth()) // Should never happen :-) - { - wxBitmap bmpbig(bundle.GetIcon()); - wxImage img = bmpbig.ConvertToImage(); - img.Rescale(sz.x, sz.y, wxIMAGE_QUALITY_HIGH); - wxBitmap bmpsmall(img); - wxIcon icosmall; icosmall.CopyFromBitmap(bmpsmall); - ico = icosmall; - bundle.AddIcon(ico); - } - return ico; -} - -// Metodo fichissimo per assegnare un identificatore univoco alle icone chiamate per nome del file.* -unsigned int TArtProvider::GetIconBundleNumber(const wxArtID& id) -{ - unsigned int num = m_hmIds[id]; - if (num == 0) - { - num = 60000+m_hmIds.size(); - m_hmIds[id] = num; - } - return num; -} - -#endif - -/////////////////////////////////////////////////////////// -// xvt_sys_load_icon -/////////////////////////////////////////////////////////// - -const wxBitmap xvtart_GetToolResource(int nIcon, int nDesiredSize) -{ - if (nDesiredSize < 16) nDesiredSize = 16; else - if (nDesiredSize > 128) nDesiredSize = 128; - wxArtID id; id.Printf("%d", nIcon); - return wxArtProvider::GetBitmap(id, wxART_TOOLBAR, wxSize(nDesiredSize, nDesiredSize)); -} - -const wxIcon xvtart_GetIconResource(int nIcon, const char* client, const int size) -{ - wxASSERT(_TheArtProvider != NULL); - - if (nIcon <= 0) - nIcon = ICON_RSRC; - - wxArtID id; id.Printf("%d", nIcon); - wxArtClient cl = client && * client ? client : wxART_OTHER; - wxSize sz(size, size); - return _TheArtProvider->GetIcon(id, cl, sz); -} - -unsigned int xvt_sys_load_icon(const char* file) -{ - wxASSERT(_TheArtProvider != NULL); - const wxArtID id = file; - const wxIcon ico = _TheArtProvider->GetIcon(id); - return ico.IsOk() ? _TheArtProvider->GetIconBundleNumber(id) : ICON_RSRC; -} - -WX_DECLARE_HASH_MAP(int, wxCursor, wxIntegerHash, wxIntegerEqual, TCursorHashTable); - -const wxCursor xvtart_GetCursorResource(int rid) -{ - static TCursorHashTable _nice_cursors; - wxCursor cursor = _nice_cursors[rid]; - - if (!cursor.IsOk()) - { - switch (rid) - { - case CURSOR_CROCE: cursor = wxCURSOR_CROSS; break; - case CURSOR_IBEAM: cursor = wxCURSOR_IBEAM; break; - default: - { - const wxString strName = xvtart_GetResourceName("Cursor", rid); - if (::wxFileExists(strName)) - { - if (strName.Find(".ico") > 0) - cursor = wxCursor(strName, wxBITMAP_TYPE_ICO); - else - cursor = wxCursor(strName, wxBITMAP_TYPE_CUR); - } - } - break; - } - if (!cursor.IsOk()) - { - wxFAIL_MSG(_("Invalid cursor")); - cursor = *wxSTANDARD_CURSOR; - } - - _nice_cursors[rid] = cursor; - } - return cursor; -} - -/////////////////////////////////////////////////////////// -// TAuiManager -/////////////////////////////////////////////////////////// - -/* +#include "wxinc.h" + +#include "xvt.h" +#include "xvtart.h" +#include "oswin32.h" + +#include +#include +#include + +wxString xvtart_GetResourceIni() +{ + DIRECTORY dir; xvt_fsys_get_default_dir(&dir); + wxString str = dir.path; + str += "/res/resource.ini"; + return str; +} + +wxString xvtart_GetResourceName(const char* type, int rid) +{ + wxString strName(type); strName << "s"; + wxString strKey; strKey.Printf("%d", rid); + + DIRECTORY dir; xvt_fsys_get_default_dir(&dir); + wxString startup_dir = dir.path; + + if ((rid == ICON_RSRC || rid == 0) && strName == "Icons") + { + int i = 1; + switch (xvt_sys_get_os_version()) + { + case XVT_WS_WIN_2000: + case XVT_WS_WIN_2003: i = 0; break; // Cerco prima l'icona a 256 colori + default : i = 1; break; // Cerco solo l'icona in RGBA + } + for (; i < 2; i++) + { + const char* const oem_var = i == 0 ? "Icon256" : "Icon"; + char name[MAX_PATH]; + if (xvt_sys_get_oem_string(oem_var, "", name, sizeof(name))) + { + wxFileName fname(startup_dir + "/setup/" + name); + if (fname.FileExists()) + { + fname.Normalize(); + strName = fname.GetFullPath().Lower(); + return strName; + } + } + } + } + + wxString val; + char* buff = val.GetWriteBuf(MAX_PATH); + xvt_sys_get_profile_string(xvtart_GetResourceIni(), strName, strKey, "", buff, MAX_PATH); + val.UngetWriteBuf(); + + if (!val.IsEmpty()) + { + strName = startup_dir; + strName += "/custom/"; + strName += val; + + if (!wxFileExists(strName)) + { + strName = startup_dir; + strName += "/res/"; + strName += val; + } + + wxFileName fname(strName); + fname.Normalize(); + strName = fname.GetFullPath().Lower(); + } + else + strName.Empty(); + + return strName; +} + +/////////////////////////////////////////////////////////// +// TArtProvider +/////////////////////////////////////////////////////////// + +class TArtProvider : public wxArtProvider +{ +#if !wxCHECK_VERSION(2,9,0) + WX_DECLARE_STRING_HASH_MAP(wxIconBundle, TIconBundleHashTable); + TIconBundleHashTable m_hmBundles; + + WX_DECLARE_STRING_HASH_MAP(unsigned, TIconIdHashTable); + TIconIdHashTable m_hmIds; +#endif + +protected: + virtual wxBitmap CreateBitmap(const wxArtID& id, const wxArtClient& client, const wxSize& size); + virtual wxIconBundle CreateIconBundle(const wxArtID& id, const wxArtClient& client); + +public: +#if !wxCHECK_VERSION(2,9,0) + wxIconBundle GetIconBundle(const wxArtID& id, const wxArtClient& client); + wxIcon GetIcon(const wxArtID& id, const wxArtClient& client = wxART_OTHER, const wxSize& size = wxDefaultSize); + wxSize GetNativeSizeHint(const wxArtClient& client); +#endif + unsigned int GetIconBundleNumber(const wxArtID& id); +}; + +TArtProvider* _TheArtProvider = NULL; + +void xvtart_Init() +{ + if (_TheArtProvider == NULL) + _TheArtProvider = new TArtProvider; + wxArtProvider::Push(_TheArtProvider); +} + +wxBitmap TArtProvider::CreateBitmap(const wxArtID& id, const wxArtClient& client, const wxSize& size) +{ + wxString strName; + + long tool = -1; + if (id.StartsWith(wxT("wxART"))) + { + if (id == wxART_ERROR) tool = 201; else + if (id == wxART_HELP) tool = 163; else + if (id == wxART_INFORMATION) tool = 162; else + if (id == wxART_MISSING_IMAGE) tool = 100; else + if (id == wxART_NEW) tool = 105; else + if (id == wxART_QUESTION) tool = 202; else + if (id == wxART_QUIT) tool = 114; else + if (id == wxART_WARNING) tool = 203; else + ; + } + else + id.ToLong(&tool); + + if (tool > 0) + { + strName = xvtart_GetResourceName("Tool", tool); + if (strName.IsEmpty() || !::wxFileExists(strName)) + strName = xvtart_GetResourceName("Tool", 100); // Default empty icon + } + else + strName = id; + + if (!strName.IsEmpty() && ::wxFileExists(strName)) + { + if (strName.EndsWith(".ico")) + { + const wxIcon ico = GetIcon(strName, client, size); + return wxBitmap(ico); + } + else + { + int sx = size.x, sy = size.y; + if (sx <= 0 || sy <= 0) + { + const wxSize sz = GetNativeSizeHint(client); + if (sx <= 0) sx = sz.x; + if (sy <= 0) sy = sz.y; + } + wxImage img(strName, wxBITMAP_TYPE_ANY); + img.Rescale(sx, sy, wxIMAGE_QUALITY_HIGH); + return wxBitmap(img); + } + } + + return wxNullBitmap; +} + +wxIconBundle TArtProvider::CreateIconBundle(const wxArtID& id, const wxArtClient& WXUNUSED(client)) +{ + wxString strName = id; + + long nIco = -1; + if (id.StartsWith(wxT("wxART"))) + { + if (id == wxART_EXECUTABLE_FILE) nIco = ICON_RSRC; else + ; + } + else + id.ToLong(&nIco); + + if (nIco > 0) + strName = xvtart_GetResourceName("Icon", nIco); + + wxIconBundle ib; + bool bFound = false; + if (::wxFileExists(strName)) + { + const bool bLog = wxLog::EnableLogging(false); // Evita segnalazione di errore di formato icona + if (strName.EndsWith(wxT(".ico"))) + { + ib.AddIcon(strName, wxBITMAP_TYPE_ICO); + bFound = true; + } + else + { + ib.AddIcon(OsWin32_LoadIcon(strName)); + bFound = true; + } + wxLog::EnableLogging(bLog); + + for (wxCoord s = 16; s <= 48; s += 16) + { + const wxIcon smico = ib.GetIcon(s); + if (smico.GetWidth() != s) + { + wxBitmap bmpbig(ib.GetIcon()); + wxImage img = bmpbig.ConvertToImage(); + img.Rescale(s, s, wxIMAGE_QUALITY_HIGH); + wxBitmap bmpsmall(img); + wxIcon icosmall; icosmall.CopyFromBitmap(bmpsmall); + ib.AddIcon(icosmall); + } + } + } + else + { + if (!strName.IsEmpty()) // Getione caso strName=".ext" + { + ib.AddIcon(OsWin32_LoadIcon(strName)); + bFound = true; + } + } + + if (!bFound && nIco == ICON_RSRC) + { + strName.Printf("%d", ICON_RSRC); // id puo' essere wxART_EXECUTABLE_FILE + ib.AddIcon(wxIcon(strName, wxBITMAP_TYPE_ICO_RESOURCE)); + } + + return ib; +} + +#if !wxCHECK_VERSION(2,9,0) + +wxSize TArtProvider::GetNativeSizeHint(const wxArtClient& client) +{ + int ix = 32, iy = 32; + + if (client == wxART_FRAME_ICON) + { + const int x = wxSystemSettings::GetMetric(wxSYS_SMALLICON_X); + const int y = wxSystemSettings::GetMetric(wxSYS_SMALLICON_Y); + if (x > 0 && y > 0) + { ix = x; iy = y; } + else + { ix /= 2; iy /= 2; } + } + else + { + const int x = wxSystemSettings::GetMetric(wxSYS_ICON_X); + const int y = wxSystemSettings::GetMetric(wxSYS_ICON_Y); + if (x > 0 && y > 0) + { ix = x; iy = y; } + if (client == wxART_MESSAGE_BOX) + { ix *= 2; iy *= 2; } + } + + return wxSize(ix,iy); +} + +wxIconBundle TArtProvider::GetIconBundle(const wxArtID& id, const wxArtClient& client) +{ + TIconBundleHashTable::iterator it = m_hmBundles.find(id); + if (it == m_hmBundles.end()) + { + const wxIconBundle b = CreateIconBundle(id, client); + m_hmBundles[id] = b; + + unsigned long uid = 0; + if (!id.ToULong(&uid)) + { + wxString numid; numid.Printf(wxT("%lu"), GetIconBundleNumber(id)); + m_hmBundles[numid] = b; + } + + return b; + } + return it->second; +} + +wxIcon TArtProvider::GetIcon(const wxArtID& id, const wxArtClient& client, const wxSize& size) +{ + wxIconBundle bundle = GetIconBundle(id, client); + const wxSize sz = size == wxDefaultSize ? GetNativeSizeHint(client) : size; + wxIcon ico = bundle.GetIcon(sz); + if (ico.IsOk() && sz.x != ico.GetWidth()) // Should never happen :-) + { + wxBitmap bmpbig(bundle.GetIcon()); + wxImage img = bmpbig.ConvertToImage(); + img.Rescale(sz.x, sz.y, wxIMAGE_QUALITY_HIGH); + wxBitmap bmpsmall(img); + wxIcon icosmall; icosmall.CopyFromBitmap(bmpsmall); + ico = icosmall; + bundle.AddIcon(ico); + } + return ico; +} + +// Metodo fichissimo per assegnare un identificatore univoco alle icone chiamate per nome del file.* +unsigned int TArtProvider::GetIconBundleNumber(const wxArtID& id) +{ + unsigned int num = m_hmIds[id]; + if (num == 0) + { + num = 60000+m_hmIds.size(); + m_hmIds[id] = num; + } + return num; +} + +#endif + +/////////////////////////////////////////////////////////// +// xvt_sys_load_icon +/////////////////////////////////////////////////////////// + +const wxBitmap xvtart_GetToolResource(int nIcon, int nDesiredSize) +{ + if (nDesiredSize < 16) nDesiredSize = 16; else + if (nDesiredSize > 128) nDesiredSize = 128; + wxArtID id; id.Printf("%d", nIcon); + return wxArtProvider::GetBitmap(id, wxART_TOOLBAR, wxSize(nDesiredSize, nDesiredSize)); +} + +const wxIcon xvtart_GetIconResource(int nIcon, const char* client, const int size) +{ + wxASSERT(_TheArtProvider != NULL); + + if (nIcon <= 0) + nIcon = ICON_RSRC; + + wxArtID id; id.Printf("%d", nIcon); + wxArtClient cl = client && * client ? client : wxART_OTHER; + wxSize sz(size, size); + return _TheArtProvider->GetIcon(id, cl, sz); +} + +unsigned int xvt_sys_load_icon(const char* file) +{ + wxASSERT(_TheArtProvider != NULL); + const wxArtID id = file; + const wxIcon ico = _TheArtProvider->GetIcon(id); + return ico.IsOk() ? _TheArtProvider->GetIconBundleNumber(id) : ICON_RSRC; +} + +WX_DECLARE_HASH_MAP(int, wxCursor, wxIntegerHash, wxIntegerEqual, TCursorHashTable); + +const wxCursor xvtart_GetCursorResource(int rid) +{ + static TCursorHashTable _nice_cursors; + wxCursor cursor = _nice_cursors[rid]; + + if (!cursor.IsOk()) + { + switch (rid) + { + case CURSOR_CROCE: cursor = wxCURSOR_CROSS; break; + case CURSOR_IBEAM: cursor = wxCURSOR_IBEAM; break; + default: + { + const wxString strName = xvtart_GetResourceName("Cursor", rid); + if (::wxFileExists(strName)) + { + if (strName.Find(".ico") > 0) + cursor = wxCursor(strName, wxBITMAP_TYPE_ICO); + else + cursor = wxCursor(strName, wxBITMAP_TYPE_CUR); + } + } + break; + } + if (!cursor.IsOk()) + { + wxFAIL_MSG(_("Invalid cursor")); + cursor = *wxSTANDARD_CURSOR; + } + + _nice_cursors[rid] = cursor; + } + return cursor; +} + +/////////////////////////////////////////////////////////// +// TAuiManager +/////////////////////////////////////////////////////////// + +/* class TAuiManager : public wxAuiManager { public: @@ -395,7 +395,7 @@ public: static bool BaseColours(wxColour& base, wxColour& light, wxColour& dark, wxColour& text); TAuiManager(); }; - + bool TAuiManager::BaseColours(wxColour& base, wxColour& light, wxColour& dark, wxColour& text) { const wxSize sz(256,256); @@ -465,9 +465,9 @@ TAuiManager::TAuiManager() { SetArtProvider(new TDockArt); } -*/ - -wxAuiManager* xvtart_CreateManager(wxWindow* win) -{ - return new wxAuiManager(win); // will be TAUIManager -} +*/ + +wxAuiManager* xvtart_CreateManager(wxWindow* win) +{ + return new wxAuiManager(win); // will be TAUIManager +}