示例#1
0
void SymbianDLLMapImp::OnUnload(void* pDLLEntryPoint)
{
    DLLMapInfo* pInfo = FindInfo(pDLLEntryPoint);

    HX_ASSERT(pInfo);
    if (pInfo)
    {
        if (pInfo->OnUnload())
        {
            // This was the last unload for this DLL.
            // Remove it from our list and destroy the info

            LISTPOSITION pos = m_libList.GetHeadPosition();
            while(pInfo && pos)
            {
                if (pInfo == (DLLMapInfo*)m_libList.GetAt(pos))
                {
                    m_libList.RemoveAt(pos);
                    HX_DELETE(pInfo);
                }
                else
                {
                    m_libList.GetNext(pos);
                }
            }
        }
    }
}
示例#2
0
int wxIconStateInfoDB::GetIconId(const wxString& name, int state, bool enabled) const
{
    wxIconStateInfo* info = FindInfo(name);
    if (!info)
        return -1;
    return info->GetIconId(state, enabled);
}
示例#3
0
void C4Language::LoadInfos(C4Group &hGroup)
{
	char strEntry[_MAX_FNAME + 1];
	char *strTable;
	// Look for language string tables
	hGroup.ResetSearch();
	while (hGroup.FindNextEntry(C4CFN_Language, strEntry))
		// For now, we will only load info on the first string table found for a given
		// language code as there is currently no handling for selecting different string tables
		// of the same code - the system always loads the first string table found for a given code
		if (!FindInfo(GetFilenameOnly(strEntry) + SLen(GetFilenameOnly(strEntry)) - 2))
			// Load language string table
			if (hGroup.LoadEntry(strEntry, &strTable, 0, 1))
			{
				// New language info
				C4LanguageInfo *pInfo = new C4LanguageInfo;
				// Get language code by entry name
				SCopy(GetFilenameOnly(strEntry) + SLen(GetFilenameOnly(strEntry)) - 2, pInfo->Code, 2);
				SCapitalize(pInfo->Code);
				// Get language name, info, fallback from table
				CopyResStr("IDS_LANG_NAME", strTable, pInfo->Name);
				CopyResStr("IDS_LANG_INFO", strTable, pInfo->Info);
				CopyResStr("IDS_LANG_FALLBACK", strTable, pInfo->Fallback);
				// Safety: pipe character is not allowed in any language info string
				SReplaceChar(pInfo->Name, '|', ' ');
				SReplaceChar(pInfo->Info, '|', ' ');
				SReplaceChar(pInfo->Fallback, '|', ' ');
				// Delete table
				delete [] strTable;
				// Add info to list
				pInfo->Next = Infos;
				Infos = pInfo;
			}
}
示例#4
0
bool wxIconStateInfoDB::SetIconId(const wxString& name, int state, bool enabled, int iconId)
{
    wxIconStateInfo* info = FindInfo(name);
    if (!info)
        return FALSE;
    info->SetIconId(state, enabled, iconId);
    return TRUE;
}
示例#5
0
const LibInfo& LibMgr::GetInfo(Library lib)
{
	if (s_LibInfos.find(lib) == s_LibInfos.end()) {
		FindInfo(lib);
	}
	
	return s_LibInfos.at(lib);
}
示例#6
0
// Easy way of initialising both the image list and the
// info db. It will generate image ids itself while appending the icon.
bool wxIconStateInfoDB::AddInfo(const wxString& name, const wxIcon& icon, int state, bool enabled)
{
    wxASSERT (m_imageList != NULL);
    
    wxIconStateInfo* info = FindInfo(name);
    if (!info)
    {
        info = new wxIconStateInfo(name);
        Append(info);
    }
    info->SetIconId(state, enabled, m_imageList->Add(icon));
    return TRUE;
}
示例#7
0
wxIcon wxIconStateInfoDB::GetIcon(const wxString& name, int state, bool enabled) const
{
    wxASSERT( m_imageList != NULL );
    
    wxIconStateInfo* info = FindInfo(name);
    if (!info)
        return wxNullIcon;
    int id = info->GetIconId(state, enabled);
    if (id < 0)
        return wxNullIcon;
    else
        return m_imageList->GetImage(id); // Doesn't exist
}
示例#8
0
/*
 * InfoSize -- return size of demand info section
 */
unsigned InfoSize( imp_image_handle *ii, imp_mod_handle im,
                        unsigned item, unsigned entry )
{
    demand_info         *dmnd;
    section_info        *inf;

    dmnd = &ModPointer( ii, im )->di[item];
    if( entry >= dmnd->u.entries )
        return( 0 );
    entry += dmnd->info_off;
    inf = FindInfo( ii, im );
    return( DMND_SIZE( inf, entry ) );
}
示例#9
0
文件: hash.c 项目: pilotniq/VoxiUtil
int HashAdd(HashTable ht, void *data)
/* Adds data to the specified hashtable. If an equivalent record (according to
   ht->compData() ) exists, no adding is done. Returns 1 on success, 0 on 
   failure. */
{
  int retval = 1;
  unsigned int hashval = ht->calcIndx(data)%ht->size;
  HashInfoPtr newInfo;

  ErrPushFunc("HashAdd");
  if(FindInfo(ht, data, hashval))
    retval=0;
  else {
    if( (newInfo = (HashInfoPtr)malloc(sizeof(struct HiPtr))) != NULL ) {
      int error;

      newInfo->data = data;
      newInfo->next = ht->infoArray[hashval];
      newInfo->firstCursor = NULL;
#if defined (_POSIX_SEMAPHORES) && defined (_POSIX_THREADS)
      error = sem_init( &(newInfo->cursorListSemaphore), 0, 1 );
      if (error != 0) {
        retval = 0;
        goto ERR_RETURN;
      }
#endif
      /* I believe this is an atomic action and therefore needs not be 
         protected by a semaphore to be thread-safe.
     
         Can this be guaranteed? What does the pthreads package say about
         atomicity? Anyway, the elementCount needs to be semaphored methinks.
 
         /Erl 981015
      */
      ht->infoArray[hashval] = newInfo;
      ht->elementCount++;
    }
    else {
      retval = 0;
      goto ERR_RETURN;
    }
  }

 ERR_RETURN:
  ErrPopFunc();
  return(retval);
}
示例#10
0
文件: hash.c 项目: pilotniq/VoxiUtil
void *HashFind(HashTable ht, void *data)
/* If a data record matching 'data' is found in ht, a pointer to it is 
   returned.  Otherwise NULL. */
{
  void *foundData;
  HashInfoPtr tmp;

  /* ErrPushFunc("HashFind"); */
  
  assert( ht != NULL && ht->size != 0 );
  
  foundData=NULL;
  if((tmp = FindInfo(ht, data, ht->calcIndx(data) % ht->size)) != NULL) {
    foundData=tmp->data;
  }
  /* ErrPopFunc(); */
  return(foundData);
}
示例#11
0
mod_info *ModPointer( imp_image_handle *ii, imp_mod_handle mod )
{
    info_block          *blk;
    mod_table           *tbl;
    unsigned            index;
    section_info        *inf;

    inf = FindInfo( ii, mod );
    if( inf == NULL ) return( NULL );
    index = mod - inf->mod_base_idx;
    for( blk = inf->mod_info; blk != NULL; blk = blk->next ) {
        tbl = blk->link;
        if( index < tbl->count ) {
            return( (mod_info *)((byte *)blk->info + tbl->mod_off[ index ]) );
        }
        index -= tbl->count;
    }
    return( NULL );
}
示例#12
0
/*
//    Return name pattern manipulator string
*/
static const char *GetNamePattern( SYM_HANDLE sym_handle )
{
    char                 *pattern;
    SYM_ENTRY            sym;
    aux_info             *inf;

    inf = FindInfo( &sym, sym_handle );
#ifdef __SEH__
    if(( sym_handle == SymTryInit )
      || ( sym_handle == SymTryFini )
      || ( sym_handle == SymTryUnwind )
      || ( sym_handle == SymExcept )) {
        pattern = "*";
    } else {
#endif
        inf = LangInfo( sym.mods, inf );
        if( sym.flags & SYM_FUNCTION ) {
            pattern = inf->objname;
#if ( _CPU == 386 ) || ( _CPU == 8086 )
            if( VarFunc( &sym ) ) {
                if( inf == &DefaultInfo )
                    inf = DftCallConv;
                if( inf == &StdcallInfo ) {
                    pattern = CdeclInfo.objname;
                } else if( inf == &FastcallInfo ) {
                    pattern = CdeclInfo.objname;
                }
            }
#endif
            if( pattern == NULL ) {
                pattern =  TS_CODE_MANGLE;
            }
        } else {
            pattern = VarNamePattern( inf );
            if( pattern == NULL ) {
                pattern =  TS_DATA_MANGLE;
            }
        }
#ifdef __SEH__
    }       // close that else
#endif
    return( pattern );
}
示例#13
0
void SymbianDLLMapImp::OnLoad(void* pDLLEntryPoint)
{
    DLLMapInfo* pInfo = FindInfo(pDLLEntryPoint);

    if (!pInfo)
    {
        pInfo = new DLLMapInfo(pDLLEntryPoint);

        if (pInfo && !m_libList.AddHead(pInfo))
        {
            // The AddHead() failed
            HX_DELETE(pInfo);
        }
    }

    if (pInfo)
    {
        pInfo->OnLoad();
    }
}
示例#14
0
static walk_result WlkClear( imp_image_handle *ii, imp_mod_handle im, void *d )
{
    unsigned            dmnd;
    mod_info            *mp;
    section_info        *sect;
    int                 entry;
    unsigned            real_entry;
    pointer_int         *lnk;

    d = d;
    mp = ModPointer( ii, im );
    sect = FindInfo( ii, im );
    for( dmnd = DMND_FIRST; dmnd < DMND_NUM; ++dmnd ) {
        for( entry = mp->di[dmnd].u.entries-1; entry >= 0; --entry ) {
            real_entry = entry + mp->di[dmnd].info_off;
            lnk = &GET_LINK( sect, real_entry );
            if( IS_RESIDENT( *lnk ) ) {
                Unload( MK_DMND_PTR( *lnk ) );
            }
        }
    }
    return( WR_CONTINUE );
}
示例#15
0
search_result LookupGblAddr( imp_image_handle *ii, address addr,
                        imp_sym_handle *is )
{
    section_info        *inf;
    info_block          *curr;
    search_result       sr = SR_NONE;

    is->u.gbl = NULL;
    SET_GBLNAMEOFF( ii );
    inf = FindInfo( ii, is->im );
    curr = inf->gbl;
    for( ;; ) {
        if( curr == NULL ) break;
        if( addr.sect_id == 0 || addr.sect_id == inf->sect_id ) {
            sr = LkupGblAddr( curr, is, addr.mach );
            if( sr == SR_EXACT ) break;
        }
        curr = curr->next;
    }
    if( is->u.gbl == NULL ) return( SR_NONE );
    GblCreate( is, is->u.gbl );
    return( sr == SR_EXACT ? SR_EXACT : SR_CLOSEST );
}
示例#16
0
/*
//    This section is NOT 8086 and 386 , i.e.,
//        _AXP
//        _PPC
//        _MIPS
//
//    pass auxiliary information to back end
*/
CGPOINTER FEAuxInfo( CGPOINTER req_handle, int request )
{
    aux_info                *inf;
    auto SYM_ENTRY          sym;
    static hw_reg_set       save_set;

    switch( request ) {
    case SOURCE_LANGUAGE:
        return( (CGPOINTER)"C" );
    case OBJECT_FILE_NAME:
        return( (CGPOINTER)ObjFileName() );
    case REVISION_NUMBER:
        return( (CGPOINTER)(pointer_int)II_REVISION );
    case AUX_LOOKUP:
        return( req_handle );
    case SOURCE_NAME:
        if( SrcFName == ModuleName ) {
            return( (CGPOINTER)FNameFullPath( FNames ) );
        } else {
            return( (CGPOINTER)ModuleName );
        }
    case CALL_CLASS:
        {
            static call_class cclass;

            cclass = GetCallClass( req_handle );
            return( (CGPOINTER)&cclass );
        }
    case NEXT_LIBRARY:
    case LIBRARY_NAME:
        return( NextLibrary( (int)(pointer_int)req_handle, request ) );
    case NEXT_IMPORT:
    case IMPORT_NAME:
        return( NextImport( (int)(pointer_int)req_handle, request ) );
    case NEXT_IMPORT_S:
    case IMPORT_NAME_S:
        return( NextImportS( (int)(pointer_int)req_handle, request ) );
    case NEXT_ALIAS:
    case ALIAS_NAME:
    case ALIAS_SYMBOL:
    case ALIAS_SUBST_NAME:
    case ALIAS_SUBST_SYMBOL:
        return( NextAlias( (int)(pointer_int)req_handle, request ) );
    case FREE_SEGMENT:
        return( NULL );
    case TEMP_LOC_NAME:
        return( (CGPOINTER)(pointer_int)TEMP_LOC_QUIT );
    case TEMP_LOC_TELL:
        return( NULL );
    case NEXT_DEPENDENCY:
        if( CompFlags.emit_dependencies )
            return( (CGPOINTER)NextDependency( (FNAMEPTR)req_handle ) );
        return( NULL );
    case DEPENDENCY_TIMESTAMP:
        return( (CGPOINTER)getFileDepTimeStamp( (FNAMEPTR)req_handle ) );
    case DEPENDENCY_NAME:
        return( (CGPOINTER)FNameFullPath( (FNAMEPTR)req_handle ) );
    default:
        break;
    }

    inf = FindInfo( &sym, req_handle );
    switch( request ) {
    case SAVE_REGS:
        if( req_handle != 0 ) {
            inf = LangInfo( sym.mods, inf );
        } else {
            sym.mods = 0;
        }
        save_set = inf->save;
        return( (CGPOINTER)&save_set );
    case RETURN_REG:
        if( req_handle != 0 ) {
            inf = LangInfo( sym.mods, inf );
        }
        return( (CGPOINTER)&inf->returns );
    case CALL_BYTES:
        return( (CGPOINTER)inf->code );
    case PARM_REGS:
        if( req_handle != 0 ) {
            inf = LangInfo( sym.mods, inf );
            if( inf->code == NULL && VarFunc( &sym ) ) {
                return( (CGPOINTER)DefaultVarParms );
            }
        }
        return( (CGPOINTER)inf->parms );
    default:
        break;
    }
    return( NULL );
}
示例#17
0
void *InfoLoad( imp_image_handle *ii, imp_mod_handle im, unsigned item,
                unsigned entry, void (*clear)(void *, void *) )
{
    demand_ctrl         *section;
    demand_info         *info;
    section_info        *sect;
    unsigned long       tmpoff;
    pointer_int         *lnk;
    unsigned            size;

    ++TimeStamp;
    if( TimeStamp == 0 ) { /* TimeStamp wrapped */
        TimeStamp = 1;
        for(section = DemandList; section != NULL; section = section->link) {
            section->time_stamp = 0;
        }
    }
    info = &ModPointer( ii, im )->di[ item ];
    if( entry >= info->u.entries )
        return( NULL );
    entry += info->info_off;
    sect = FindInfo( ii, im );
    lnk = &GET_LINK( sect, entry );
    if( IS_RESIDENT( *lnk ) ) {
        section = MK_DMND_PTR( *lnk );
    } else {
        /* section not loaded */
        size = DMND_SIZE( sect, entry );
        if( (LastDemand->owner == NULL || LastDemand->size < size)
            && LastDemand->locks == 0 ) {
            /* keep largest section in LastDemand */
            section = LastDemand;
            Unload( LastDemand );
        } else {
            /* allocate some memory */
            section = DCAlloc( _demand_size( size ) );
            if( section == NULL ) {
                if( LastDemand->locks != 0 )
                    return( NULL );
                /* no memory, use last chance */
                section = LastDemand;
                Unload( LastDemand );
            }
        }
        tmpoff = MK_DMND_OFFSET( *lnk );
        if( InfoRead( sect, tmpoff, size, section->buff ) != DS_OK ) {
            if( section != LastDemand )
                DCFree( section );
            return( NULL );
        }
        section->size = size;
        section->locks = 0;
        section->clear = clear;
        section->owner = lnk;
        section->save  = *lnk;
        *lnk = STASH_DMND_PTR( section );
        if( section != LastDemand ) {
            section->link = DemandList;
            DemandList = section;
        }
    }
    section->time_stamp = TimeStamp; /* for removal priority */
    section->locks++;
    return( section->buff );
}
示例#18
0
/*
//    pass auxiliary information to back end
*/
VOIDPTR FEAuxInfo( CGSYM_HANDLE cgsym_handle, int request )
{
    SYM_HANDLE              sym_handle = cgsym_handle;
    struct aux_info         *inf;
    auto SYM_ENTRY          sym;
    static hw_reg_set       save_set;

    switch( request ) {
    case SOURCE_LANGUAGE:
        return( "C" );
    case OBJECT_FILE_NAME:
        return( (VOIDPTR)ObjFileName( OBJ_EXT ) );
    case REVISION_NUMBER:
        return( (VOIDPTR)II_REVISION );
    case AUX_LOOKUP:
        return( (VOIDPTR)sym_handle );
    case SOURCE_NAME:
        if( SrcFName == ModuleName ) {
            return( FNameFullPath( FNames ) );
        } else {
            return( ModuleName );
        }
    case CALL_CLASS:
        GetCallClass( sym_handle );
        return( &CallClass );
    case NEXT_LIBRARY:
    case LIBRARY_NAME:
        return( NextLibrary( (int)sym_handle, request ) );
    case NEXT_IMPORT:
    case IMPORT_NAME:
        return( NextImport( (int)sym_handle, request ) );
    case NEXT_IMPORT_S:
    case IMPORT_NAME_S:
        return( NextImportS( (int)sym_handle, request ) );
    case NEXT_ALIAS:
    case ALIAS_NAME:
    case ALIAS_SYMBOL:
    case ALIAS_SUBST_NAME:
    case ALIAS_SUBST_SYMBOL:
        return( NextAlias( (int)sym_handle, request ) );
    case FREE_SEGMENT:
        return( NULL );
    case TEMP_LOC_NAME:
        return( (char *)TEMP_LOC_QUIT );
    case TEMP_LOC_TELL:
        return( NULL );
    case NEXT_DEPENDENCY:                               /* 03-dec-92 */
        if( CompFlags.emit_dependencies )
            return( NextDependency( (FNAMEPTR) cgsym_handle ) );
        return( NULL );
    case DEPENDENCY_TIMESTAMP:
        return( getFileDepTimeStamp( (FNAMEPTR)cgsym_handle ) );
    case DEPENDENCY_NAME:
        return( FNameFullPath( (FNAMEPTR)cgsym_handle ) );
    default:
        break;
    }

    inf = FindInfo( &sym, sym_handle );
    switch( request ) {
    case SAVE_REGS:
        if( sym_handle != 0 ) {
            inf = LangInfo( sym.attrib, inf );
        } else {
            sym.attrib = 0;
        }
        save_set = inf->save;
        return( &save_set );
    case RETURN_REG:
        if( sym_handle != 0 ) {
            inf = LangInfo( sym.attrib, inf );
        }
        return( &inf->returns );
    case CALL_BYTES:
        return( inf->code );
    case PARM_REGS:
        if( sym_handle != 0 ) {
            inf = LangInfo( sym.attrib, inf );
            if( inf->code == NULL && VarFunc( &sym ) ) {
                return( DefaultVarParms );
            }
        }
        return( inf->parms );
    default:
        break;
    }
    return( NULL );
}
示例#19
0
struct aux_info *InfoLookup( SYMPTR sym )
{
    char                  *name;
    struct aux_info       *inf;
    struct aux_entry      *ent;

    name = sym->name;
    inf = &DefaultInfo;         /* assume default */
    if( name == NULL )
        return( inf );                   /* 01-jun-90 */
    ent = AuxLookup( name );
    if( ent != NULL )
        inf = ent->info;
    if( ( ent == NULL ) || (sym->flags & SYM_INTRINSIC) ) {
        if( sym->flags & SYM_DEFINED )
            return( inf );
        if( !(sym->flags & SYM_INTRINSIC) ) {
            if( memcmp( name, "_inline_", 8 ) != 0 )
                return( inf );
            name += 8;
        }
#if ( _CPU == 8086 ) || ( _CPU == 386 )
        {
            struct inline_funcs     *ifunc;

            ifunc = IF_Lookup( name );
            if( ifunc == NULL )
                return( inf );
  #if ( _CPU == 8086 )
            if( HW_CEqual( ifunc->returns, HW_DX_AX )
              || HW_CEqual( ifunc->returns, HW_DS_SI )
              || HW_CEqual( ifunc->returns, HW_ES_DI )
              || HW_CEqual( ifunc->returns, HW_CX_DI ) ) {
                if( SizeOfArg( sym->sym_type->object ) != 4 ) {
  #else
            if( HW_CEqual( ifunc->returns, HW_DX_AX )
              || HW_CEqual( ifunc->returns, HW_DS_ESI )
              || HW_CEqual( ifunc->returns, HW_ES_EDI )
              || HW_CEqual( ifunc->returns, HW_CX_DI ) ) {
                if( SizeOfArg( sym->sym_type->object ) != 6 ) {
  #endif
                    return( inf );
                }
            }
            inf = &InlineInfo;
            inf->cclass = (WatcallInfo.cclass & FAR) | MODIFY_EXACT;
            if( (sym->flags & SYM_INTRINSIC) && ( ent != NULL ) )
                inf->cclass |= ent->info->cclass;
            inf->code = ifunc->code;
            inf->parms = ifunc->parms;
            inf->returns = ifunc->returns;
  #if ( _CPU == 8086 )
            if( !HW_CEqual( inf->returns, HW_AX )
              && !HW_CEqual( inf->returns, HW_EMPTY ) ) {
  #else
            if( !HW_CEqual( inf->returns, HW_EAX )
              && !HW_CEqual( inf->returns, HW_EMPTY ) ) {
  #endif
                inf->cclass |= SPECIAL_RETURN;
            }
            HW_CAsgn( inf->streturn, HW_EMPTY );
            inf->save = ifunc->save;
            inf->objname = WatcallInfo.objname; /* 26-jan-93 */
            inf->use = 1;
        }
#endif
    }
    return( inf );
}

struct aux_info *FindInfo( SYM_ENTRY *sym, SYM_HANDLE sym_handle )
{
    SYM_ENTRY           sym_typedef;
    struct aux_entry    *ent;
    TYPEPTR             typ;
    struct aux_info     *inf;

    inf = &DefaultInfo;         /* assume default */
    if( sym_handle == 0 )
        return( inf );

    SymGet( sym, sym_handle );
#if _CPU == 386
    if( (sym_handle == SymSTOSB) || (sym_handle == SymSTOSD) ) {
        return( &STOSBInfo );
    } else if( sym_handle == SymFinally ) {
        static byte_seq FinallyCode = { 1, { 0xc3 } };  /* ret */

        InlineInfo = WatcallInfo;
        InlineInfo.code = &FinallyCode;
        return( &InlineInfo );
    } else if( sym_handle == SymTryFini ) {
        static hw_reg_set TryFiniParms[] = {
            HW_D( HW_EAX ),
            HW_D( HW_EMPTY )
        };
        static byte_seq TryFiniCode = {
            6, { 0x64, 0xA3, 0, 0, 0, 0 }
        };  /* mov fs:[0],eax */

        InlineInfo = WatcallInfo;
        InlineInfo.parms = TryFiniParms;
        InlineInfo.code = &TryFiniCode;
        return( &InlineInfo );
    }
#endif
    if( !(sym->flags & SYM_TEMP) ) {
        /* not an indirect func call*/
        inf = InfoLookup( sym );
    }
    if( inf == &DefaultInfo ) {
        typ = SkipDummyTypedef( sym->sym_type );
        if( typ->decl_type == TYPE_TYPEDEF ) {
            SymGet( &sym_typedef, typ->u.typedefn );
            if( sym_typedef.name != NULL ) {
                ent = AuxLookup( sym_typedef.name );
                if( ent != NULL ) {
                    inf = ent->info;
                }
            }
        }
    }
#if _CPU == 386
    if( ( inf->flags & AUX_FLAG_FAR16 )
      || ( sym->attrib & FLAG_FAR16 ) ) {
        if( ( (sym->attrib & FLAG_LANGUAGES) == LANG_PASCAL )
          || ( inf->cclass & REVERSE_PARMS ) ) {
            return( &Far16PascalInfo );
        } else {
            return( &Far16CdeclInfo );
        }
    }
#endif
    return( inf );
}

int FunctionAborts( SYM_ENTRY *sym, SYM_HANDLE sym_handle )  /* 09-apr-93 */
{
    struct aux_entry    *ent;

    if( sym_handle != 0 ) {              /* 19-apr-93 */
        SymGet( sym, sym_handle );
        ent = AuxLookup( SymName( sym, sym_handle ) );
        if( ent != NULL ) {
            if( ent->info->cclass & SUICIDAL ) {
                return( 1 );
            }
        }
    }
    return( 0 );
}

void GetCallClass( SYM_HANDLE sym_handle )
{
    struct aux_info     *inf;
    SYM_ENTRY           sym;

    CallClass = DefaultInfo.cclass;
    if( sym_handle != 0 ) {
        inf = FindInfo( &sym, sym_handle );
        if( sym.flags & SYM_FUNCTION ) {
            if( inf != &DefaultInfo ) {
                CallClass = inf->cclass;
            } else {
                CallClass = GetLangInfo( sym.attrib )->cclass;
#if _CPU == 8086
                if( TargSys == TS_WINDOWS ) {
                    if( sym.attrib & (LANG_CDECL | LANG_PASCAL) ) {
                        CallClass |= FAT_WINDOWS_PROLOG;
                    }
                }
#endif
            }
#if ( _CPU == 8086 ) || ( _CPU == 386 )
            if( CompFlags.emit_names ) {
                CallClass |= EMIT_FUNCTION_NAME;
            }
            if( sym.attrib & FLAG_FAR ) {
                CallClass |= FAR;
                if( sym.attrib & FLAG_NEAR ) {
                    CallClass |= INTERRUPT;
                }
            } else if( sym.attrib & FLAG_NEAR ) {
                CallClass &= ~ FAR;
            }
#endif
#ifdef DLL_EXPORT
            if( sym.attrib & FLAG_EXPORT ) {  /* 12-mar-90 */
                CallClass |= DLL_EXPORT;
            }
#endif
#ifdef LOAD_DS_ON_ENTRY
            if( sym.attrib & FLAG_LOADDS ) {  /* 26-apr-90 */
  #if 0 /* John - 11-mar-93 */          /* 21-feb-93 */
                if( TargSys == TS_WINDOWS ) {
                    CallClass |= FAT_WINDOWS_PROLOG;
                } else {
                    CallClass |= LOAD_DS_ON_ENTRY;
                }
  #else
                CallClass |= LOAD_DS_ON_ENTRY;
  #endif
            }
#endif
#ifdef MAKE_CALL_INLINE
            if( IsInLineFunc( sym_handle ) ) {
                CallClass |= MAKE_CALL_INLINE;
            }
#endif
            if( VarFunc( &sym ) ) {
                CallClass |= CALLER_POPS | HAS_VARARGS;
            }
        }
    }
#ifdef REVERSE
    CallClass &= ~ REVERSE_PARMS;               /* 28-may-89 */
#endif
#if ( _CPU == 8086 ) || ( _CPU == 386 )
    if( sym_handle != 0 && sym.flags & SYM_FUNC_NEEDS_THUNK ) {
        CallClass |= THUNK_PROLOG;
    }
#endif
#ifdef PROLOG_HOOKS
    if( CompFlags.ep_switch_used != 0 ) {
        CallClass |= PROLOG_HOOKS;
    }
#endif
#ifdef EPILOG_HOOKS
    if( CompFlags.ee_switch_used != 0 ) {
        CallClass |= EPILOG_HOOKS;
    }
#endif
#ifdef GROW_STACK
    if( CompFlags.sg_switch_used ) {
        CallClass |= GROW_STACK;
    }
#endif
#ifdef TOUCH_STACK
    if( CompFlags.st_switch_used ) {
        CallClass |= TOUCH_STACK;
    }
#endif
}

static time_t *getFileDepTimeStamp( FNAMEPTR flist )
{
    static time_t            stamp;

#if ( ( _CPU == 8086 ) || ( _CPU == 386 ) ) && ( COMP_CFG_COFF == 0 )
    stamp = _timet2dos( flist->mtime );
#else
    stamp = flist->mtime;
#endif
    return( &stamp );
}

/*
//    NextLibrary
//        Called (indirectly) from the code generator to inject automagically defined symbols.
//    Inputs:
//        index    (n-1)
//            Usually called from a loop until we return 0/NULL to show no more libraries
//        request
//            NEXT_LIBRARY
//                examines the current flags to see if any libraries should be
//                automagically referenced and returns the relevant index if so.
//            LIBRARY_NAME
//                returns the requested name.
//
*/
static VOIDPTR NextLibrary( int index, aux_class request )
{
    struct library_list *liblist;
    char                *name = NULL;
    int                 i;

    i = 0;
    if( request == NEXT_LIBRARY )
        ++index;

    for( liblist = HeadLibs; liblist; liblist = liblist->next ) {
        name = &liblist->prio;
        ++i;
        if( i == index ) {
            break;
        }
    }
    if( liblist == NULL ) {
        switch( index - i ) {
        case 1: /* return 1 for CLIB */
            name = CLIB_Name;
            if( CompFlags.emit_library_any )
                break;
            if( CompFlags.emit_library_with_main ) {
                if( CompFlags.has_main )
                    break;
                if( CompFlags.has_winmain )
                    break;
                if( CompFlags.bd_switch_used )
                    break;
                if( CompFlags.has_libmain )
                    break;
                if( CompFlags.bm_switch_used )
                    break;  /* JBS */
                ++index;
            } else {
                name = NULL;
                index = 0;              // indicate all done
            }
            break;
        /*
        //    MATHLIB is always referenced as a default library because
        //    the linker wont include anything without a 'real' referenced
        //    symbol
        */
        case 2: /* return 2 for MATHLIB */
            name = MATHLIB_Name;
            break;
        case 3: /* return 3 for EMULIB */
            name = EmuLib_Name;
            if( EmuLib_Name != NULL )
                break;
            // fall through
        case 4: /* used to be PCODE */
            name = NULL;
            index = 0;                  // indicate all done
            break;
        default:
            break;
        }
    }
    /*
    //    return library name, or
    */
    if( request == LIBRARY_NAME )
        return( name );
    /*
    //    library index
    */
    return( (char *)index );
}

//    NextAlias
//        Called (indirectly) from the code generator to go through the list of
//        linker aliases.
//    Inputs:
//        index    (n-1)
//            Called from a loop until we return 0/NULL to show no more aliases
//        request
//            NEXT_ALIAS
//                returns the index of next alias in the list, or zero if none.
//            ALIAS_NAME
//                returns the alias name, or NULL if alias refers to a symbol.
//            ALIAS_SYMBOL
//                returns the alias symbol, or NULL if alias refers to a name.
//            ALIAS_SUBSTITUTE
//                returns the name to be substituted for the alias.
//
// Note: One of ALIAS_NAME and ALIAS_SYMBOL will always be 0/NULL and the other
// will be valid, depending on which form of the pragma was used.
static VOIDPTR NextAlias( int index, aux_class request )
{
    struct alias_list   *aliaslist;
    SYM_HANDLE          alias_sym = NULL;
    SYM_HANDLE          subst_sym = NULL;
    const char          *alias_name = NULL;
    const char          *subst_name = NULL;
    int                 i;

    if( request == NEXT_ALIAS )
        ++index;

    for( i = 1, aliaslist = AliasHead; aliaslist; aliaslist = aliaslist->next, ++i ) {
        alias_name = aliaslist->name;
        alias_sym  = aliaslist->a_sym;
        subst_name = aliaslist->subst;
        subst_sym  = aliaslist->s_sym;
        if( i == index ) {
            break;
        }
    }
    if( aliaslist == NULL )
        index = 0;          /* no (more) aliases */

    if( request == ALIAS_NAME ) {
        return( (VOIDPTR)alias_name );
    } else if( request == ALIAS_SYMBOL ) {
        return( (VOIDPTR)alias_sym );
    } else if( request == ALIAS_SUBST_NAME ) {
        return( (VOIDPTR)subst_name );
    } else if( request == ALIAS_SUBST_SYMBOL ) {
        return( (VOIDPTR)subst_sym );
    } else {    // this had better be a NEXT_ALIAS request
        return( (VOIDPTR)index );
    }
}

/* Return the size of function parameters or -1 if size could
 * not be determined (symbol isn't a function or is variadic)
 */
static int GetParmsSize( CGSYM_HANDLE sym_handle )
{
    int         total_parm_size = 0;
    int         parm_size;
    TYPEPTR     fn_typ;
    TYPEPTR     *parm;
    TYPEPTR     typ;
    SYM_ENTRY   sym;

    SymGet( &sym, sym_handle );
    fn_typ = sym.sym_type;
    SKIP_TYPEDEFS( fn_typ );
    if( fn_typ->decl_type == TYPE_FUNCTION ) {
        parm = fn_typ->u.fn.parms;
        if( parm != NULL ) {
            for( ; (typ = *parm); ++parm ) {
                if( typ->decl_type == TYPE_DOT_DOT_DOT ) {
                    total_parm_size = -1;
                    break;
                }

                SKIP_TYPEDEFS( typ );
                if( typ->decl_type == TYPE_VOID )
                    break;

                parm_size = TypeSize( typ );
                parm_size = (parm_size + sizeof( target_int ) - 1)
                            & -sizeof( target_int );
                total_parm_size += parm_size;
            }
        }
    } else {
        total_parm_size = -1;
    }
    return( total_parm_size );
}

/*
//    Return name pattern manipulator string
*/
static char *GetNamePattern( CGSYM_HANDLE sym_handle )
{
    char                 *pattern;
    SYM_ENTRY            sym;
    struct aux_info      *inf;

    inf = FindInfo( &sym, sym_handle );
#ifdef __SEH__
    if(( sym_handle == SymTryInit )
      || ( sym_handle == SymTryFini )
      || ( sym_handle == SymTryUnwind )
      || ( sym_handle == SymExcept )) {
        pattern = "*";
    } else {
#endif
        inf = LangInfo( sym.attrib, inf );
        if( sym.flags & SYM_FUNCTION ) {
            pattern = inf->objname;
#if ( _CPU == 386 ) || ( _CPU == 8086 )
            if( VarFunc( &sym ) ) {
                if( inf == &DefaultInfo )
                    inf = DftCallConv;
                if( inf == &StdcallInfo ) {
                    pattern = CdeclInfo.objname;
                } else if( inf == &FastcallInfo ) {
                    pattern = CdeclInfo.objname;
                }
            }
#endif
            if( pattern == NULL ) {
                pattern =  TS_CODE_MANGLE;
            }
        } else {
            pattern = VarNamePattern( inf );
            if( pattern == NULL ) {
                pattern =  TS_DATA_MANGLE;
            }
        }
#ifdef __SEH__
    }       // close that else
#endif
    return( pattern );
}
示例#20
0
/*
//    This section is for
//        8086
//        386
//
//    pass auxiliary information to back end
*/
CGPOINTER FEAuxInfo( CGPOINTER req_handle, int request )
{
    aux_info             *inf;
    auto SYM_ENTRY       sym;
    static hw_reg_set    save_set;

    switch( request ) {
    case SOURCE_LANGUAGE:
        return( (CGPOINTER)"C" );
    case STACK_SIZE_8087:
        return( (CGPOINTER)(pointer_int)Stack87 );
    case CODE_GROUP:
        return( (CGPOINTER)GenCodeGroup );
    case DATA_GROUP:
        return( (CGPOINTER)DataSegName );
    case OBJECT_FILE_NAME:
        return( (CGPOINTER)ObjFileName() );
    case REVISION_NUMBER:
        return( (CGPOINTER)(pointer_int)II_REVISION );
    case AUX_LOOKUP:
        return( req_handle );
    case PROEPI_DATA_SIZE:
        return( (CGPOINTER)(pointer_int)ProEpiDataSize );
    case DBG_PREDEF_SYM:
        return( (CGPOINTER)SymDFAbbr );
    case P5_CHIP_BUG_SYM:
        return( (CGPOINTER)SymChipBug );
    case CODE_LABEL_ALIGNMENT:
        {
            static  unsigned char   Alignment[] = { 2, 1, 1 };

            if( OptSize == 0 )
                Alignment[1] = TARGET_INT;

            return( (CGPOINTER)Alignment );
        }
    case CLASS_NAME:
        return( (CGPOINTER)SegClassName( (segment_id)(pointer_int)req_handle ) );
    case USED_8087:
        CompFlags.pgm_used_8087 = 1;
        return( NULL );
  #if _CPU == 386
    case P5_PROF_DATA:
        return( (CGPOINTER)FunctionProfileBlock );
    case P5_PROF_SEG:
        return( (CGPOINTER)(pointer_int)FunctionProfileSegment );
  #endif
    case SOURCE_NAME:
        if( SrcFName == ModuleName ) {
            return( (CGPOINTER)FNameFullPath( FNames ) );
        } else {
            return( (CGPOINTER)ModuleName );
        }
    case CALL_CLASS:
        {
            static call_class cclass;

            cclass = GetCallClass( req_handle );
            return( (CGPOINTER)&cclass );
        }
    case FREE_SEGMENT:
        return( NULL );
    case NEXT_LIBRARY:
    case LIBRARY_NAME:
        return( NextLibrary( (int)(pointer_int)req_handle, request ) );
    case NEXT_IMPORT:
    case IMPORT_NAME:
        return( NextImport( (int)(pointer_int)req_handle, request ) );
    case NEXT_IMPORT_S:
    case IMPORT_NAME_S:
        return( NextImportS( (int)(pointer_int)req_handle, request ) );
    case NEXT_ALIAS:
    case ALIAS_NAME:
    case ALIAS_SYMBOL:
    case ALIAS_SUBST_NAME:
    case ALIAS_SUBST_SYMBOL:
        return( NextAlias( (int)(pointer_int)req_handle, request ) );
    case TEMP_LOC_NAME:
        return( (CGPOINTER)(pointer_int)TEMP_LOC_QUIT );
    case TEMP_LOC_TELL:
        return( NULL );
    case NEXT_DEPENDENCY:
        if( CompFlags.emit_dependencies )
            return( (CGPOINTER)NextDependency( (FNAMEPTR)req_handle ) );
        return( NULL );
    case DEPENDENCY_TIMESTAMP:
        return( (CGPOINTER)getFileDepTimeStamp( (FNAMEPTR)req_handle ) );
    case DEPENDENCY_NAME:
        return( (CGPOINTER)FNameFullPath( (FNAMEPTR)req_handle ) );
    case PEGGED_REGISTER:
        return( (CGPOINTER)SegPeggedReg( (segment_id)(pointer_int)req_handle ) );
    default:
        break;
    }

    inf = FindInfo( &sym, req_handle );
    switch( request ) {
    case SAVE_REGS:
        if( req_handle != 0 ) {
            inf = LangInfo( sym.mods, inf );
        } else {
            sym.mods = 0;
        }
        save_set = inf->save;
        if( sym.mods & FLAG_SAVEREGS ) {
            HW_CTurnOn( save_set, HW_SEGS );
        }

  #ifdef __SEH__
        if( (SYM_HANDLE)req_handle == SymTryInit ) {
            HW_CTurnOff( save_set, HW_SP );
        }
  #endif
        return( (CGPOINTER)&save_set );
    case RETURN_REG:
        if( req_handle != 0 ) {
            inf = LangInfo( sym.mods, inf );
        }
        return( (CGPOINTER)&inf->returns );
    case CALL_BYTES:
        return( (CGPOINTER)inf->code );
    case PARM_REGS:
  #ifdef __SEH__
        if(( (SYM_HANDLE)req_handle == SymTryInit )
          || ( (SYM_HANDLE)req_handle == SymTryFini )
          || ( (SYM_HANDLE)req_handle == SymTryUnwind )
          || ( (SYM_HANDLE)req_handle == SymExcept )) {
            return( (CGPOINTER)TryParms );
        }
  #endif
        if( req_handle != 0 ) {
            inf = LangInfo( sym.mods, inf );
            if( inf->code == NULL && VarFunc( &sym ) ) {
                return( (CGPOINTER)DefaultVarParms );
            }
        }
        return( (CGPOINTER)inf->parms );
    case STRETURN_REG:
        if( req_handle != 0 ) {
            inf = LangInfo( sym.mods, inf );
        }
        return( (CGPOINTER)&inf->streturn );
    default:
        break;
    }
    return( NULL );
}
示例#21
0
static aux_info *InfoLookup( SYMPTR sym )
{
    char            *name;
    aux_info        *inf;
    aux_entry       *ent;

    name = sym->name;
    inf = &DefaultInfo;         /* assume default */
    if( name == NULL )
        return( inf );
    ent = AuxLookup( name );
    if( ent != NULL )
        inf = ent->info;
    if( ( ent == NULL ) || (sym->flags & SYM_INTRINSIC) ) {
        if( sym->flags & SYM_DEFINED )
            return( inf );
        if( (sym->flags & SYM_INTRINSIC) == 0 ) {
            if( memcmp( name, "_inline_", 8 ) != 0 )
                return( inf );
            name += 8;
        }
#if ( _CPU == 8086 ) || ( _CPU == 386 )
        {
            const inline_funcs  *ifunc;

            ifunc = IF_Lookup( name );
            if( ifunc == NULL )
                return( inf );
  #if ( _CPU == 8086 )
            if( HW_CEqual( ifunc->returns, HW_DX_AX )
              || HW_CEqual( ifunc->returns, HW_DS_SI )
              || HW_CEqual( ifunc->returns, HW_ES_DI )
              || HW_CEqual( ifunc->returns, HW_CX_DI ) ) {
                if( SizeOfArg( sym->sym_type->object ) != 4 ) {
  #else
            if( HW_CEqual( ifunc->returns, HW_DX_AX )
              || HW_CEqual( ifunc->returns, HW_DS_ESI )
              || HW_CEqual( ifunc->returns, HW_ES_EDI )
              || HW_CEqual( ifunc->returns, HW_CX_DI ) ) {
                if( SizeOfArg( sym->sym_type->object ) != 6 ) {
  #endif
                    return( inf );
                }
            }
            inf = &InlineInfo;
            inf->cclass = (WatcallInfo.cclass & FAR_CALL) | MODIFY_EXACT;
            if( (sym->flags & SYM_INTRINSIC) && ( ent != NULL ) )
                inf->cclass |= ent->info->cclass;
            inf->code = ifunc->code;
            inf->parms = ifunc->parms;
            inf->returns = ifunc->returns;
  #if ( _CPU == 8086 )
            if( !HW_CEqual( inf->returns, HW_AX )
              && !HW_CEqual( inf->returns, HW_EMPTY ) ) {
  #else
            if( !HW_CEqual( inf->returns, HW_EAX )
              && !HW_CEqual( inf->returns, HW_EMPTY ) ) {
  #endif
                inf->cclass |= SPECIAL_RETURN;
            }
            HW_CAsgn( inf->streturn, HW_EMPTY );
            inf->save = ifunc->save;
            inf->objname = WatcallInfo.objname;
            inf->use = 1;
        }
#endif
    }
    return( inf );
}

aux_info *FindInfo( SYMPTR sym, SYM_HANDLE sym_handle )
{
    SYM_ENTRY       sym_typedef;
    aux_entry       *ent;
    TYPEPTR         typ;
    aux_info        *inf;

    inf = &DefaultInfo;         /* assume default */
    if( sym_handle == SYM_NULL )
        return( inf );

    SymGet( sym, sym_handle );
#if _CPU == 386
    if( (sym_handle == SymSTOSB) || (sym_handle == SymSTOSD) ) {
        return( &STOSBInfo );
    } else if( sym_handle == SymFinally ) {
        InlineInfo = WatcallInfo;
        InlineInfo.code = (byte_seq *)&FinallyCode;
        return( &InlineInfo );
    } else if( sym_handle == SymTryFini ) {
        InlineInfo = WatcallInfo;
        InlineInfo.parms = TryFiniParms;
        InlineInfo.code = (byte_seq *)&TryFiniCode;
        return( &InlineInfo );
    }
#endif
    if( (sym->flags & SYM_TEMP) == 0 ) {
        /* not an indirect func call*/
        inf = InfoLookup( sym );
    }
    if( inf == &DefaultInfo ) {
        typ = sym->sym_type;
        SKIP_DUMMY_TYPEDEFS( typ );
        if( typ->decl_type == TYPE_TYPEDEF ) {
            SymGet( &sym_typedef, typ->u.typedefn );
            if( sym_typedef.name != NULL ) {
                ent = AuxLookup( sym_typedef.name );
                if( ent != NULL ) {
                    inf = ent->info;
                }
            }
        }
    }
#if _CPU == 386
    if( (inf->flags & AUX_FLAG_FAR16) || (sym->mods & FLAG_FAR16) ) {
        if( (sym->mods & MASK_LANGUAGES) == LANG_PASCAL || (inf->cclass & REVERSE_PARMS) ) {
            return( &Far16PascalInfo );
        } else {
            return( &Far16CdeclInfo );
        }
    }
#endif
    return( inf );
}

bool FunctionAborts( SYMPTR sym, SYM_HANDLE sym_handle )
{
    aux_entry    *ent;

    if( sym_handle != SYM_NULL ) {
        SymGet( sym, sym_handle );
        ent = AuxLookup( SymName( sym, sym_handle ) );
        if( ent != NULL ) {
            if( ent->info->cclass & SUICIDAL ) {
                return( TRUE );
            }
        }
    }
    return( FALSE );
}

call_class GetCallClass( SYM_HANDLE sym_handle )
{
    aux_info            *inf;
    SYM_ENTRY           sym;
    call_class          cclass;

    cclass = DefaultInfo.cclass;
    if( sym_handle != SYM_NULL ) {
        inf = FindInfo( &sym, sym_handle );
        if( sym.flags & SYM_FUNCTION ) {
            if( inf != &DefaultInfo ) {
                cclass = inf->cclass;
            } else {
                cclass = GetLangInfo( sym.mods )->cclass;
#if _CPU == 8086
                if( TargSys == TS_WINDOWS ) {
                    if( sym.mods & (LANG_CDECL | LANG_PASCAL) ) {
                        cclass |= FAT_WINDOWS_PROLOG;
                    }
                }
#endif
            }
#if ( _CPU == 8086 ) || ( _CPU == 386 )
            if( CompFlags.emit_names ) {
                cclass |= EMIT_FUNCTION_NAME;
            }
            if( sym.mods & FLAG_FAR ) {
                cclass |= FAR_CALL;
                if( sym.mods & FLAG_NEAR ) {
                    cclass |= INTERRUPT;
                }
            } else if( sym.mods & FLAG_NEAR ) {
                cclass &= ~ FAR_CALL;
            }
#endif
#ifdef DLL_EXPORT
            if( sym.mods & FLAG_EXPORT ) {
                cclass |= DLL_EXPORT;
            }
#endif
#ifdef LOAD_DS_ON_ENTRY
            if( sym.mods & FLAG_LOADDS ) {
  #if 0
                if( TargSys == TS_WINDOWS ) {
                    cclass |= FAT_WINDOWS_PROLOG;
                } else {
                    cclass |= LOAD_DS_ON_ENTRY;
                }
  #else
                cclass |= LOAD_DS_ON_ENTRY;
  #endif
            }
#endif
#ifdef MAKE_CALL_INLINE
            if( IsInLineFunc( sym_handle ) ) {
                cclass |= MAKE_CALL_INLINE;
            }
#endif
            if( VarFunc( &sym ) ) {
                cclass |= CALLER_POPS | HAS_VARARGS;
            }
        }
#if ( _CPU == 8086 ) || ( _CPU == 386 )
        if( sym.flags & SYM_FUNC_NEEDS_THUNK ) {
            cclass |= THUNK_PROLOG;
        }
#endif
    }
#ifdef REVERSE
    cclass &= ~ REVERSE_PARMS;
#endif
#ifdef PROLOG_HOOKS
    if( CompFlags.ep_switch_used != 0 ) {
        cclass |= PROLOG_HOOKS;
    }
#endif
#ifdef EPILOG_HOOKS
    if( CompFlags.ee_switch_used != 0 ) {
        cclass |= EPILOG_HOOKS;
    }
#endif
#ifdef GROW_STACK
    if( CompFlags.sg_switch_used ) {
        cclass |= GROW_STACK;
    }
#endif
#ifdef TOUCH_STACK
    if( CompFlags.st_switch_used ) {
        cclass |= TOUCH_STACK;
    }
#endif
    return( cclass );
}
示例#22
0
CStdWindow *CStdWindow::Init(CStdApp *pApp, const char *Title,
                             CStdWindow *pParent, bool HideCursor) {
#ifndef USE_X11
  return this;
#else
  Active = true;
  dpy = pApp->dpy;

  if (!FindInfo()) return 0;

  // Various properties
  XSetWindowAttributes attr;
  attr.border_pixel = 0;
  attr.background_pixel = 0;
  // Which events we want to receive
  attr.event_mask =
      // EnterWindowMask |
      // LeaveWindowMask |
      StructureNotifyMask | FocusChangeMask | KeyPressMask | KeyReleaseMask |
      PointerMotionMask | ButtonPressMask | ButtonReleaseMask;
  attr.colormap = XCreateColormap(dpy, DefaultRootWindow(dpy),
                                  ((XVisualInfo *)Info)->visual, AllocNone);
  unsigned long attrmask =
      CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
  Pixmap bitmap;
  if (HideCursor) {
    // Hide the mouse cursor
    XColor cursor_color;
    // We do not care what color the invisible cursor has
    memset(&cursor_color, 0, sizeof(cursor_color));
    bitmap = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), "\000", 1, 1);
    attr.cursor = XCreatePixmapCursor(dpy, bitmap, bitmap, &cursor_color,
                                      &cursor_color, 0, 0);
    attrmask |= CWCursor;
  }

  wnd = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, 640, 480, 0,
                      ((XVisualInfo *)Info)->depth, InputOutput,
                      ((XVisualInfo *)Info)->visual, attrmask, &attr);
  if (HideCursor) {
    XFreeCursor(dpy, attr.cursor);
    XFreePixmap(dpy, bitmap);
  }
  if (!wnd) {
    Log("Error creating window.");
    return 0;
  }
  // Update the XWindow->CStdWindow-Map
  CStdAppPrivate::SetWindow(wnd, this);
  if (!pApp->Priv->xic && pApp->Priv->xim) {
    pApp->Priv->xic = XCreateIC(
        pApp->Priv->xim, XNClientWindow, wnd, XNFocusWindow, wnd, XNInputStyle,
        XIMPreeditNothing | XIMStatusNothing, XNResourceName, STD_PRODUCT,
        XNResourceClass, STD_PRODUCT, NULL);
    if (!pApp->Priv->xic) {
      Log("Failed to create input context.");
      XCloseIM(pApp->Priv->xim);
      pApp->Priv->xim = 0;
    } else {
      long ic_event_mask;
      if (XGetICValues(pApp->Priv->xic, XNFilterEvents, &ic_event_mask, NULL) ==
          NULL)
        attr.event_mask |= ic_event_mask;
      XSelectInput(dpy, wnd, attr.event_mask);
      XSetICFocus(pApp->Priv->xic);
    }
  }
  // We want notification of closerequests and be killed if we hang
  Atom WMProtocols[2];
  char *WMProtocolnames[] = {"WM_DELETE_WINDOW", "_NET_WM_PING"};
  XInternAtoms(dpy, WMProtocolnames, 2, false, WMProtocols);
  XSetWMProtocols(dpy, wnd, WMProtocols, 2);
  // Let the window manager know our pid so it can kill us
  Atom PID = XInternAtom(pApp->dpy, "_NET_WM_PID", false);
  int32_t pid = getpid();
  if (PID != None)
    XChangeProperty(pApp->dpy, wnd, PID, XA_CARDINAL, 32, PropModeReplace,
                    reinterpret_cast<const unsigned char *>(&pid), 1);
  // Title and stuff
  XTextProperty title_property;
  StdStrBuf tbuf;
  tbuf.Copy(Title ? Title : "");
  char *tbufstr = tbuf.getMData();
  // char * title = "Clonk Endeavour";
  XStringListToTextProperty(&tbufstr, 1, &title_property);
  // State and Icon
  XWMHints *wm_hint = XAllocWMHints();
  wm_hint->flags = StateHint | InputHint | IconPixmapHint | IconMaskHint;
  wm_hint->initial_state = NormalState;
  wm_hint->input = True;
  // Trust XpmCreatePixmapFromData to not modify the xpm...
  XpmCreatePixmapFromData(dpy, wnd, const_cast<char **>(c4x_xpm),
                          &wm_hint->icon_pixmap, &wm_hint->icon_mask, 0);
  // Window class
  XClassHint *class_hint = XAllocClassHint();
  class_hint->res_name = STD_PRODUCT;
  class_hint->res_class = STD_PRODUCT;
  XSetWMProperties(dpy, wnd, &title_property, &title_property, pApp->Priv->argv,
                   pApp->Priv->argc, 0, wm_hint, class_hint);
  // Set "parent". Clonk does not use "real" parent windows, but multiple
  // toplevel windows.
  if (pParent) XSetTransientForHint(dpy, wnd, pParent->wnd);
  // Show window
  XMapWindow(dpy, wnd);
  // Clean up
  // The pixmap has to stay as long as the window exists, so it does not hurt to
  // never free it.
  // XFreePixmap(dpy,xwmh->icon_pixmap);
  // XFreePixmap(dpy,xwmh->icon_mask);
  XFree(title_property.value);
  Hints = wm_hint;
  XFree(class_hint);

  // Render into whole window
  renderwnd = wnd;

  return this;
#endif  // USE_X11
}