Patch level : 2.0 nopatch
Files correlati : xvadll.dll Ricompilazione Demo : [ ] Commento : Primo supporto per sintesi vocale. Velocizzata tramite cache l'impostazione delle stampanti di rete. git-svn-id: svn://10.65.10.50/trunk@11493 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
		
							parent
							
								
									abba234805
								
							
						
					
					
						commit
						66acb35beb
					
				@ -711,3 +711,44 @@ bool OsWin32_GotoUrl(const char* url, const char* action)
 | 
			
		||||
  UINT error = UINT(winst);  // Tutto 'sto giro per evitare un warning
 | 
			
		||||
  return error > 32;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef SPEECH_API
 | 
			
		||||
 | 
			
		||||
#include "\Programmi\Microsoft Speech SDK 5.1\Include\sapi.h"
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -36,3 +36,9 @@ bool OsWin32_SL_Logout() ;
 | 
			
		||||
bool OsWin32_SL_ReadBlock(unsigned short reg, unsigned short size, unsigned short* data);
 | 
			
		||||
bool OsWin32_SL_WriteBlock(unsigned short reg, unsigned short size, const unsigned short* data);
 | 
			
		||||
 | 
			
		||||
#ifdef SPEECH_API
 | 
			
		||||
bool OsWin32_InitializeSpeech();
 | 
			
		||||
bool OsWin32_Speak(const char* text, bool async);
 | 
			
		||||
void OsWin32_DeinitializeSpeech();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1132,6 +1132,35 @@ TTaskWin::~TTaskWin()
 | 
			
		||||
  _nice_windows.Delete((WINDOW)this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////
 | 
			
		||||
// Speech support
 | 
			
		||||
///////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
// 0   Errors
 | 
			
		||||
// 1   Warnings
 | 
			
		||||
// 2   Messages
 | 
			
		||||
// 3   Requests
 | 
			
		||||
// 7   Buttons 
 | 
			
		||||
static int m_nSpeechMode = 0;
 | 
			
		||||
 | 
			
		||||
void xvt_dm_enable_speech(int mode)
 | 
			
		||||
{
 | 
			
		||||
#ifdef SPEECH_API
 | 
			
		||||
  m_nSpeechMode = mode;
 | 
			
		||||
#ifdef WIN32
 | 
			
		||||
  if (m_nSpeechMode != 0)
 | 
			
		||||
  {
 | 
			
		||||
    if (!OsWin32_InitializeSpeech())
 | 
			
		||||
      m_nSpeechMode = 0;
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    OsWin32_DeinitializeSpeech();
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////
 | 
			
		||||
// XVT
 | 
			
		||||
///////////////////////////////////////////////////////////
 | 
			
		||||
@ -1147,6 +1176,10 @@ void xvt_app_create(int argc, char **argv, unsigned long flags,
 | 
			
		||||
	::wxInitAllImageHandlers();
 | 
			
		||||
  xvt_fsys_get_default_dir(NULL); // Init Startup Directory
 | 
			
		||||
 | 
			
		||||
#ifdef SPEECH_API
 | 
			
		||||
  xvt_dm_enable_speech(0xFF);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	_task_win_handler = eh;
 | 
			
		||||
	_config_ = config;
 | 
			
		||||
 | 
			
		||||
@ -1219,6 +1252,10 @@ void xvt_app_destroy(void)
 | 
			
		||||
{
 | 
			
		||||
	wxTheApp->ExitMainLoop();
 | 
			
		||||
  _task_win->Destroy();
 | 
			
		||||
 | 
			
		||||
#ifdef SPEECH_API
 | 
			
		||||
  xvt_dm_enable_speech(0x00);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DRAW_CTOOLS* xvt_app_get_default_ctools(DRAW_CTOOLS *ct)
 | 
			
		||||
@ -1514,6 +1551,21 @@ COLOR xvt_dm_post_choose_color(WINDOW win, COLOR xc)
 | 
			
		||||
  return xc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BOOLEAN xvt_dm_post_speech(const char* text, int priority, BOOLEAN async)
 | 
			
		||||
{
 | 
			
		||||
  BOOLEAN ok = FALSE;
 | 
			
		||||
#ifdef SPEECH_API
 | 
			
		||||
  if ((m_nSpeechMode & (1 << priority)) != 0)
 | 
			
		||||
  {
 | 
			
		||||
#ifdef WIN32
 | 
			
		||||
    ok = OsWin32_Speak(text, async != 0);
 | 
			
		||||
#else
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
  return ok;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ASK_RESPONSE xvt_dm_post_ask(const char* Btn1, const char*Btn2, const char* Btn3, const char* fmt)
 | 
			
		||||
{
 | 
			
		||||
  int nFlags = wxCENTRE | wxICON_QUESTION | wxYES_NO;
 | 
			
		||||
@ -1525,18 +1577,31 @@ ASK_RESPONSE xvt_dm_post_ask(const char* Btn1, const char*Btn2, const char* Btn3
 | 
			
		||||
  else
 | 
			
		||||
    nFlags |= wxCANCEL;
 | 
			
		||||
 | 
			
		||||
  int answer = wxMessageBox(fmt, _GetAppTitle(), nFlags);
 | 
			
		||||
  xvt_dm_post_speech(fmt, 3, TRUE);
 | 
			
		||||
  const int answer = wxMessageBox(fmt, _GetAppTitle(), nFlags);
 | 
			
		||||
 | 
			
		||||
  switch(answer)
 | 
			
		||||
  {
 | 
			
		||||
  case wxYES: xvt_dm_post_speech("si", 7, TRUE); break;
 | 
			
		||||
  case wxNO : xvt_dm_post_speech("no", 7, TRUE); break;
 | 
			
		||||
  default   : xvt_dm_post_speech("annulla", 7, TRUE); break;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return answer == wxYES ? RESP_DEFAULT : (answer == wxNO ? RESP_2 : RESP_3);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void xvt_dm_post_error(const char *fmt)
 | 
			
		||||
{
 | 
			
		||||
  xvt_dm_post_speech(fmt, 1, TRUE);
 | 
			
		||||
  wxMessageBox(fmt, _GetAppTitle(), wxOK | wxCENTRE | wxICON_ERROR);
 | 
			
		||||
  xvt_dm_post_speech("OK", 7, TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void xvt_dm_post_fatal_exit(const char *fmt)
 | 
			
		||||
{
 | 
			
		||||
  xvt_dm_post_speech(fmt, 1, TRUE);
 | 
			
		||||
  wxLogFatalError(fmt);
 | 
			
		||||
  xvt_dm_post_speech("OK", 7, TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static wxString MakeFileName(const wxChar* name, const wxChar* ext)
 | 
			
		||||
@ -1604,12 +1669,16 @@ BOOLEAN xvt_dm_post_font_sel(WINDOW win, XVT_FNTID font_id, PRINT_RCD *precp, un
 | 
			
		||||
 | 
			
		||||
void xvt_dm_post_message(const char *fmt)
 | 
			
		||||
{
 | 
			
		||||
  xvt_dm_post_speech(fmt, 2, TRUE);
 | 
			
		||||
  wxMessageBox(fmt, _GetAppTitle(), wxOK | wxCENTRE | wxICON_INFORMATION);
 | 
			
		||||
  xvt_dm_post_speech("OK", 7, TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void xvt_dm_post_note(const char *fmt)
 | 
			
		||||
{
 | 
			
		||||
  xvt_dm_post_speech(fmt, 2, TRUE);
 | 
			
		||||
  wxMessageBox(fmt, _GetAppTitle(), wxOK | wxCENTRE | wxICON_EXCLAMATION);
 | 
			
		||||
  xvt_dm_post_speech("OK", 7, TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char* xvt_dm_post_string_prompt(const char* message, char* response, int response_len)
 | 
			
		||||
@ -1622,7 +1691,9 @@ char* xvt_dm_post_string_prompt(const char* message, char* response, int respons
 | 
			
		||||
 | 
			
		||||
void xvt_dm_post_warning(const char *fmt)
 | 
			
		||||
{
 | 
			
		||||
  xvt_dm_post_speech(fmt, 1, TRUE);
 | 
			
		||||
  wxMessageBox(fmt, _GetAppTitle(), wxOK | wxCENTRE | wxICON_EXCLAMATION);
 | 
			
		||||
  xvt_dm_post_speech("OK", 7, TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////
 | 
			
		||||
@ -1793,7 +1864,6 @@ const wxBitmap& TXVT_IMAGE::Bitmap()
 | 
			
		||||
	if (m_bDirty)
 | 
			
		||||
	{
 | 
			
		||||
		m_bitmap = m_image.ConvertToBitmap();
 | 
			
		||||
//		m_image.Destroy();  // Sarebbe bello poterlo fare
 | 
			
		||||
		m_bDirty = FALSE;
 | 
			
		||||
	}
 | 
			
		||||
	return m_bitmap;
 | 
			
		||||
@ -4018,6 +4088,9 @@ long xvt_vobj_get_attr(WINDOW win, long data)
 | 
			
		||||
	case ATTR_SCREEN_WINDOW:
 | 
			
		||||
		ret = NULL_WIN;	// Non bellissimo ma per ora...
 | 
			
		||||
		break;
 | 
			
		||||
  case ATTR_SPEECH_MODE:
 | 
			
		||||
		ret = m_nSpeechMode;
 | 
			
		||||
		break;
 | 
			
		||||
  case ATTR_TASK_WINDOW:
 | 
			
		||||
		ret = long(_task_win);
 | 
			
		||||
		break;
 | 
			
		||||
@ -4147,6 +4220,7 @@ void xvt_vobj_set_attr(WINDOW win, long data, long value)
 | 
			
		||||
	case ATTR_WIN_PM_DRAWABLE_TWIN: break;      // Ignored: Always TRUE
 | 
			
		||||
  case ATTR_WIN_PM_TWIN_STARTUP_RCT: _startup_rect = *(RCT*)value; break;
 | 
			
		||||
  case ATTR_WIN_PM_TWIN_STARTUP_STYLE: break; // TBI
 | 
			
		||||
  case ATTR_SPEECH_MODE: xvt_dm_enable_speech(value); break;
 | 
			
		||||
	default: SORRY_BOX(); break;
 | 
			
		||||
	}
 | 
			
		||||
}	
 | 
			
		||||
 | 
			
		||||
@ -71,6 +71,7 @@ XVTDLL void          xvt_dm_post_note(const char *fmt);
 | 
			
		||||
XVTDLL BOOLEAN       xvt_dm_post_page_setup(PRINT_RCD *precp);
 | 
			
		||||
XVTDLL char*         xvt_dm_post_string_prompt(const char* message, char* response, int response_len);
 | 
			
		||||
XVTDLL void          xvt_dm_post_warning(const char *fmt);
 | 
			
		||||
XVTDLL BOOLEAN       xvt_dm_post_speech(const char* text, int priority, BOOLEAN async); // 0 = Error, 1 = Warning, 2 Message, ... 
 | 
			
		||||
 | 
			
		||||
// Dongle support by AGA
 | 
			
		||||
XVTDLL BOOLEAN xvt_dongle_hl_crypt(unsigned short* data);
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,7 @@
 | 
			
		||||
 *  Agreement with XVT Software.
 | 
			
		||||
 *
 | 
			
		||||
 *	$RCSfile: xvt_defs.h,v $ 
 | 
			
		||||
 *  $Revision: 1.3 $
 | 
			
		||||
 *  $Revision: 1.4 $
 | 
			
		||||
 *
 | 
			
		||||
 *  Purpose: Global XVT macro definitions.
 | 
			
		||||
 *
 | 
			
		||||
@ -474,6 +474,7 @@
 | 
			
		||||
#define ATTR_TASKWIN_TITLE_RID          (ATTR_BASE + 717)
 | 
			
		||||
#define ATTR_R40_TXEDIT_BEHAVIOR        (ATTR_BASE + 718)
 | 
			
		||||
#define ATTR_APP_CTL_FONT_RID           (ATTR_BASE + 719)
 | 
			
		||||
#define ATTR_SPEECH_MODE                (ATTR_BASE + 720) /* Added by Guy */
 | 
			
		||||
 | 
			
		||||
/* Font attributes */
 | 
			
		||||
#define ATTR_FONT_MAPPER                (ATTR_BASE + 800)
 | 
			
		||||
 | 
			
		||||
@ -57,6 +57,7 @@ class TwxPrintOut : public wxPrintout
 | 
			
		||||
protected:
 | 
			
		||||
  virtual bool HasPage(int pageNum);
 | 
			
		||||
	virtual bool OnPrintPage(int pageNum);
 | 
			
		||||
  void ResetDC();
 | 
			
		||||
 | 
			
		||||
  TPRINT_RCD* m_prcd;
 | 
			
		||||
 | 
			
		||||
@ -69,16 +70,22 @@ public:
 | 
			
		||||
static TwxPrintOut* m_po = NULL;
 | 
			
		||||
 | 
			
		||||
bool TwxPrintOut::HasPage(int pageNum)
 | 
			
		||||
{	return TRUE; }
 | 
			
		||||
{	return true; }
 | 
			
		||||
 | 
			
		||||
bool TwxPrintOut::OnPrintPage(int pageNum)
 | 
			
		||||
{	return FALSE; }
 | 
			
		||||
{	return false; }
 | 
			
		||||
 | 
			
		||||
void TwxPrintOut::InitDC(TPRINT_RCD* prcd)
 | 
			
		||||
void TwxPrintOut::ResetDC()
 | 
			
		||||
{
 | 
			
		||||
	wxDC* dc = GetDC();
 | 
			
		||||
	if (dc != NULL)
 | 
			
		||||
		delete dc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TwxPrintOut::InitDC(TPRINT_RCD* prcd)
 | 
			
		||||
{
 | 
			
		||||
  ResetDC();
 | 
			
		||||
  wxDC* dc = NULL;
 | 
			
		||||
 | 
			
		||||
  m_prcd = prcd;
 | 
			
		||||
 | 
			
		||||
@ -120,9 +127,59 @@ TwxPrintOut::TwxPrintOut(TPRINT_RCD* prcd)
 | 
			
		||||
 | 
			
		||||
TwxPrintOut::~TwxPrintOut()
 | 
			
		||||
{
 | 
			
		||||
	wxDC* dc = GetDC();
 | 
			
		||||
	if (dc != NULL)
 | 
			
		||||
		delete dc;
 | 
			
		||||
	ResetDC();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////
 | 
			
		||||
// TwxPrintOutCache
 | 
			
		||||
///////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
class TwxPrintOutCache
 | 
			
		||||
{
 | 
			
		||||
  unsigned long m_signature;
 | 
			
		||||
  TwxPrintOut* m_po;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
  unsigned long Signature(TPRINT_RCD* prcd) const;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  TwxPrintOut* Get(TPRINT_RCD* prcd);
 | 
			
		||||
  void Reset();
 | 
			
		||||
 | 
			
		||||
  TwxPrintOutCache() : m_signature(0), m_po(NULL) { }
 | 
			
		||||
  ~TwxPrintOutCache() { Reset(); }
 | 
			
		||||
} m_PrintoutCache;
 | 
			
		||||
 | 
			
		||||
unsigned long TwxPrintOutCache::Signature(TPRINT_RCD* prcd) const
 | 
			
		||||
{
 | 
			
		||||
  unsigned long signature = 1;
 | 
			
		||||
  const unsigned char* data = (const unsigned char*)prcd + 4;
 | 
			
		||||
  for (size_t i = 0; i < 32; i++)
 | 
			
		||||
    if (data[i] != 0)
 | 
			
		||||
      signature *= data[i]; 
 | 
			
		||||
  return signature;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TwxPrintOutCache::Reset()
 | 
			
		||||
{
 | 
			
		||||
  if (m_po != NULL)
 | 
			
		||||
  {
 | 
			
		||||
    delete m_po;
 | 
			
		||||
    m_po = NULL;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TwxPrintOut* TwxPrintOutCache::Get(TPRINT_RCD* prcd)
 | 
			
		||||
{
 | 
			
		||||
  unsigned long signature = Signature(prcd);
 | 
			
		||||
  if (m_po != NULL && m_signature == signature)
 | 
			
		||||
    return m_po;
 | 
			
		||||
  Reset();
 | 
			
		||||
  m_po = new TwxPrintOut(prcd);
 | 
			
		||||
  m_signature = signature;
 | 
			
		||||
 | 
			
		||||
  return m_po;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////
 | 
			
		||||
@ -157,19 +214,23 @@ BOOLEAN xvt_app_escape(int esc_code, PRINT_RCD* rcd, long* ph, long* pw, long* p
 | 
			
		||||
	case XVT_ESC_GET_PRINTER_INFO:
 | 
			
		||||
		if (rcd == NULL || xvt_print_is_valid(rcd))
 | 
			
		||||
		{
 | 
			
		||||
			const bool temp = m_po == NULL;
 | 
			
		||||
			if (temp)
 | 
			
		||||
			  m_po = new TwxPrintOut((TPRINT_RCD*)rcd);
 | 
			
		||||
  	  int w, h;
 | 
			
		||||
      if (m_po == NULL)
 | 
			
		||||
      {
 | 
			
		||||
        TwxPrintOut* po = m_PrintoutCache.Get((TPRINT_RCD*)rcd);
 | 
			
		||||
			  po->GetPPIPrinter(&w, &h);
 | 
			
		||||
			  *phr = w; *pvr = h;
 | 
			
		||||
			  po->GetPageSizePixels(&w, &h);
 | 
			
		||||
			  *pw = w; *ph = h;
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
			  m_po->GetPPIPrinter(&w, &h);
 | 
			
		||||
			  *phr = w; *pvr = h;
 | 
			
		||||
			  m_po->GetPageSizePixels(&w, &h);
 | 
			
		||||
			  *pw = w; *ph = h;
 | 
			
		||||
			if (temp)
 | 
			
		||||
			{
 | 
			
		||||
				delete m_po;
 | 
			
		||||
				m_po = NULL;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
  		return TRUE;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
@ -205,7 +266,7 @@ BOOLEAN xvt_dm_post_page_setup(PRINT_RCD* precp)
 | 
			
		||||
#else
 | 
			
		||||
		rcd->SetData((void *) &data, (unsigned int) sizeof(data));
 | 
			
		||||
#endif
 | 
			
		||||
	
 | 
			
		||||
    m_PrintoutCache.Reset();
 | 
			
		||||
		return TRUE;
 | 
			
		||||
	}
 | 
			
		||||
	return FALSE;
 | 
			
		||||
@ -220,8 +281,7 @@ long xvt_fmap_get_family_sizes(PRINT_RCD *precp, char *family, long *size_array,
 | 
			
		||||
  if (precp != NULL)
 | 
			
		||||
	{
 | 
			
		||||
#ifdef WIN32
 | 
			
		||||
  	TwxPrintOut* po = new TwxPrintOut((TPRINT_RCD*)precp);
 | 
			
		||||
		
 | 
			
		||||
  	TwxPrintOut* po = m_PrintoutCache.Get((TPRINT_RCD*)precp);
 | 
			
		||||
		size = OsWin32_EnumerateSizes(po->GetDC()->GetHDC(), family, size_array, scalable, max_sizes);
 | 
			
		||||
#else
 | 
			
		||||
		size = OsLinux_EnumerateSizes(family, size_array, scalable, max_sizes);
 | 
			
		||||
@ -239,8 +299,7 @@ long xvt_fmap_get_families(PRINT_RCD *precp, char **family_array, long max_famil
 | 
			
		||||
  if (precp != NULL)
 | 
			
		||||
	{
 | 
			
		||||
#ifdef WIN32
 | 
			
		||||
  	TwxPrintOut* po = new TwxPrintOut((TPRINT_RCD*)precp);
 | 
			
		||||
		
 | 
			
		||||
  	TwxPrintOut* po = m_PrintoutCache.Get((TPRINT_RCD*)precp);
 | 
			
		||||
		size = OsWin32_EnumerateFamilies(po->GetDC()->GetHDC(), family_array, max_families);
 | 
			
		||||
#else
 | 
			
		||||
		size = OsLinux_EnumerateFamilies(family_array, max_families);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user